@@ -198,6 +198,7 @@ class TestClass : public TestFixture {
198198 TEST_CASE (const85);
199199 TEST_CASE (const86);
200200 TEST_CASE (const87);
201+ TEST_CASE (const88);
201202 TEST_CASE (const89);
202203
203204 TEST_CASE (const_handleDefaultParameters);
@@ -6026,7 +6027,7 @@ class TestClass : public TestFixture {
60266027 " int i{};\n "
60276028 " S f() { return S(&i); }\n "
60286029 " };\n " );
6029- TODO_ASSERT_EQUALS (" [test.cpp:7]: (style, inconclusive) Technically the member function 'C::f' can be const.\n " , " " , errout.str ());
6030+ ASSERT_EQUALS (" [test.cpp:7]: (style, inconclusive) Technically the member function 'C::f' can be const.\n " , errout.str ());
60306031
60316032 checkConst (" struct S {\n "
60326033 " const int* mp{};\n "
@@ -6317,6 +6318,16 @@ class TestClass : public TestFixture {
63176318 " void g() { p->f(i); }\n "
63186319 " };\n " );
63196320 ASSERT_EQUALS (" " , errout.str ());
6321+
6322+ checkConst (" struct A {\n " // #11501
6323+ " enum E { E1 };\n "
6324+ " virtual void f(E) const = 0;\n "
6325+ " };\n "
6326+ " struct F {\n "
6327+ " A* a;\n "
6328+ " void g() { a->f(A::E1); }\n "
6329+ " };\n " );
6330+ ASSERT_EQUALS (" [test.cpp:7]: (style, inconclusive) Technically the member function 'F::g' can be const.\n " , errout.str ());
63206331 }
63216332
63226333 void const82 () { // #11513
@@ -6333,9 +6344,8 @@ class TestClass : public TestFixture {
63336344 " void h(int, int*) const;\n "
63346345 " void g() { int a; h(i, &a); }\n "
63356346 " };\n " );
6336- TODO_ASSERT_EQUALS (" [test.cpp:4]: (style, inconclusive) Technically the member function 'S::g' can be const.\n " ,
6337- " " ,
6338- errout.str ());
6347+ ASSERT_EQUALS (" [test.cpp:4]: (style, inconclusive) Technically the member function 'S::g' can be const.\n " ,
6348+ errout.str ());
63396349 }
63406350
63416351 void const83 () {
@@ -6400,7 +6410,113 @@ class TestClass : public TestFixture {
64006410 ASSERT_EQUALS (" " , errout.str ());
64016411 }
64026412
6403- void const87 () { // #11626
6413+ void const87 () {
6414+ checkConst (" struct Tokenizer {\n " // #11720
6415+ " bool isCPP() const {\n "
6416+ " return cpp;\n "
6417+ " }\n "
6418+ " bool cpp;\n "
6419+ " };\n "
6420+ " struct Check {\n "
6421+ " const Tokenizer* const mTokenizer;\n "
6422+ " const int* const mSettings;\n "
6423+ " };\n "
6424+ " struct CheckA : Check {\n "
6425+ " static bool test(const std::string& funcname, const int* settings, bool cpp);\n "
6426+ " };\n "
6427+ " struct CheckB : Check {\n "
6428+ " bool f(const std::string& s);\n "
6429+ " };\n "
6430+ " bool CheckA::test(const std::string& funcname, const int* settings, bool cpp) {\n "
6431+ " return !funcname.empty() && settings && cpp;\n "
6432+ " }\n "
6433+ " bool CheckB::f(const std::string& s) {\n "
6434+ " return CheckA::test(s, mSettings, mTokenizer->isCPP());\n "
6435+ " }\n " );
6436+ ASSERT_EQUALS (" [test.cpp:20] -> [test.cpp:15]: (style, inconclusive) Technically the member function 'CheckB::f' can be const.\n " , errout.str ());
6437+
6438+ checkConst (" void g(int&);\n "
6439+ " struct S {\n "
6440+ " struct { int i; } a[1];\n "
6441+ " void f() { g(a[0].i); }\n "
6442+ " };\n " );
6443+ ASSERT_EQUALS (" " , errout.str ());
6444+
6445+ checkConst (" struct S {\n "
6446+ " const int& g() const { return i; }\n "
6447+ " int i;\n "
6448+ " };\n "
6449+ " void h(int, const int&);\n "
6450+ " struct T {\n "
6451+ " S s;\n "
6452+ " int j;\n "
6453+ " void f() { h(j, s.g()); }\n "
6454+ " };\n " );
6455+ ASSERT_EQUALS (" [test.cpp:9]: (style, inconclusive) Technically the member function 'T::f' can be const.\n " , errout.str ());
6456+
6457+ checkConst (" struct S {\n "
6458+ " int& g() { return i; }\n "
6459+ " int i;\n "
6460+ " };\n "
6461+ " void h(int, int&);\n "
6462+ " struct T {\n "
6463+ " S s;\n "
6464+ " int j;\n "
6465+ " void f() { h(j, s.g()); }\n "
6466+ " };\n " );
6467+ ASSERT_EQUALS (" " , errout.str ());
6468+
6469+ checkConst (" struct S {\n "
6470+ " const int& g() const { return i; }\n "
6471+ " int i;\n "
6472+ " };\n "
6473+ " void h(int, const int*);\n "
6474+ " struct T {\n "
6475+ " S s;\n "
6476+ " int j;\n "
6477+ " void f() { h(j, &s.g()); }\n "
6478+ " };\n " );
6479+ ASSERT_EQUALS (" [test.cpp:9]: (style, inconclusive) Technically the member function 'T::f' can be const.\n " , errout.str ());
6480+
6481+ checkConst (" struct S {\n "
6482+ " int& g() { return i; }\n "
6483+ " int i;\n "
6484+ " };\n "
6485+ " void h(int, int*);\n "
6486+ " struct T {\n "
6487+ " S s;\n "
6488+ " int j;\n "
6489+ " void f() { h(j, &s.g()); }\n "
6490+ " };\n " );
6491+ ASSERT_EQUALS (" " , errout.str ());
6492+
6493+ checkConst (" void j(int** x);\n "
6494+ " void k(int* const* y);\n "
6495+ " struct S {\n "
6496+ " int* p;\n "
6497+ " int** q;\n "
6498+ " int* const* r;\n "
6499+ " void f1() { j(&p); }\n "
6500+ " void f2() { j(q); }\n "
6501+ " void g1() { k(&p); }\n "
6502+ " void g2() { k(q); }\n "
6503+ " void g3() { k(r); }\n "
6504+ " };\n " );
6505+ ASSERT_EQUALS (" " , errout.str ());
6506+
6507+ checkConst (" void m(int*& r);\n "
6508+ " void n(int* const& s);\n "
6509+ " struct T {\n "
6510+ " int i;\n "
6511+ " int* p;\n "
6512+ " void f1() { m(p); }\n "
6513+ " void f2() { n(&i); }\n "
6514+ " void f3() { n(p); }\n "
6515+ " };\n " );
6516+ ASSERT_EQUALS (" " , errout.str ());
6517+ }
6518+
6519+ void const88 () { // #11626
64046520 checkConst (" struct S {\n "
64056521 " bool f() { return static_cast<bool>(p); }\n "
64066522 " const int* g() { return const_cast<const int*>(p); }\n "
0 commit comments