Skip to content

Commit a5f577d

Browse files
committed
Support range-based for-loop in CheckClass::checkConst() (cppcheck-opensource#5514)
1 parent 7d8b62e commit a5f577d

2 files changed

Lines changed: 21 additions & 0 deletions

File tree

lib/checkclass.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1868,6 +1868,10 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool&
18681868
if (lhs->previous()->variable()->typeStartToken()->strAt(-1) != "const" && lhs->previous()->variable()->isPointer())
18691869
return false;
18701870
}
1871+
} else if (lhs->str() == ":" && lhs->astParent() && lhs->astParent()->str() == "(" && tok1->strAt(1) == ")") { // range-based for-loop (C++11)
1872+
// TODO: We could additionally check what is done with the elements to avoid false negatives. Here we just rely on "const" keyword being used.
1873+
if (lhs->astParent()->strAt(1) != "const")
1874+
return false;
18711875
} else {
18721876
const Variable* v2 = lhs->previous()->variable();
18731877
if (lhs->tokType() == Token::eAssignmentOp && v2)

test/testclass.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ class TestClass : public TestFixture {
170170
TEST_CASE(constFriend); // ticket #1921 - fp for friend function
171171
TEST_CASE(constUnion); // ticket #2111 - fp when there is a union
172172
TEST_CASE(constArrayOperator); // #4406
173+
TEST_CASE(constRangeBasedFor); // #5514
173174

174175
TEST_CASE(initializerListOrder);
175176
TEST_CASE(initializerListUsage);
@@ -5780,6 +5781,22 @@ class TestClass : public TestFixture {
57805781
ASSERT_EQUALS("[test.cpp:10]: (style, inconclusive) Technically the member function 'foo::c' can be const.\n", errout.str());
57815782
}
57825783

5784+
void constRangeBasedFor() { // #5514
5785+
checkConst("class Fred {\n"
5786+
" int array[256];\n"
5787+
"public:\n"
5788+
" void f1() {\n"
5789+
" for (auto & e : array)\n"
5790+
" foo(e);\n"
5791+
" }\n"
5792+
" void f2() {\n"
5793+
" for (const auto & e : array)\n"
5794+
" foo(e);\n"
5795+
" }\n"
5796+
"};");
5797+
ASSERT_EQUALS("[test.cpp:8]: (style, inconclusive) Technically the member function 'Fred::f2' can be const.\n", errout.str());
5798+
}
5799+
57835800
void checkInitializerListOrder(const char code[]) {
57845801
// Clear the error log
57855802
errout.str("");

0 commit comments

Comments
 (0)