Support range-based for-loop in CheckClass::checkConst() (#5514)

This commit is contained in:
PKEuS 2015-10-26 18:47:44 +01:00
parent 7d8b62e615
commit a5f577d179
2 changed files with 21 additions and 0 deletions

View File

@ -1868,6 +1868,10 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool&
if (lhs->previous()->variable()->typeStartToken()->strAt(-1) != "const" && lhs->previous()->variable()->isPointer())
return false;
}
} else if (lhs->str() == ":" && lhs->astParent() && lhs->astParent()->str() == "(" && tok1->strAt(1) == ")") { // range-based for-loop (C++11)
// TODO: We could additionally check what is done with the elements to avoid false negatives. Here we just rely on "const" keyword being used.
if (lhs->astParent()->strAt(1) != "const")
return false;
} else {
const Variable* v2 = lhs->previous()->variable();
if (lhs->tokType() == Token::eAssignmentOp && v2)

View File

@ -170,6 +170,7 @@ private:
TEST_CASE(constFriend); // ticket #1921 - fp for friend function
TEST_CASE(constUnion); // ticket #2111 - fp when there is a union
TEST_CASE(constArrayOperator); // #4406
TEST_CASE(constRangeBasedFor); // #5514
TEST_CASE(initializerListOrder);
TEST_CASE(initializerListUsage);
@ -5780,6 +5781,22 @@ private:
ASSERT_EQUALS("[test.cpp:10]: (style, inconclusive) Technically the member function 'foo::c' can be const.\n", errout.str());
}
void constRangeBasedFor() { // #5514
checkConst("class Fred {\n"
" int array[256];\n"
"public:\n"
" void f1() {\n"
" for (auto & e : array)\n"
" foo(e);\n"
" }\n"
" void f2() {\n"
" for (const auto & e : array)\n"
" foo(e);\n"
" }\n"
"};");
ASSERT_EQUALS("[test.cpp:8]: (style, inconclusive) Technically the member function 'Fred::f2' can be const.\n", errout.str());
}
void checkInitializerListOrder(const char code[]) {
// Clear the error log
errout.str("");