Fixed false positive "function can be const" if a non-const expression is inside []-brackets (#4406)

This commit is contained in:
PKEuS 2013-02-16 02:20:18 -08:00
parent afe45ff39f
commit d3087602a1
2 changed files with 22 additions and 1 deletions

View File

@ -1546,6 +1546,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool&
if (tok1->str() == "this" && tok1->previous()->isAssignmentOp()) if (tok1->str() == "this" && tok1->previous()->isAssignmentOp())
return(false); return(false);
const Token* jumpBackToken = 0;
const Token *lastVarTok = tok1; const Token *lastVarTok = tok1;
const Token *end = tok1; const Token *end = tok1;
for (;;) { for (;;) {
@ -1560,6 +1561,8 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool&
if (var && Token::simpleMatch(var->typeStartToken(), "std :: map")) // operator[] changes a map if (var && Token::simpleMatch(var->typeStartToken(), "std :: map")) // operator[] changes a map
return(false); return(false);
} }
if (!jumpBackToken)
jumpBackToken = end->next(); // Check inside the [] brackets
end = end->linkAt(1); end = end->linkAt(1);
} else if (end->strAt(1) == ")") } else if (end->strAt(1) == ")")
end = end->next(); end = end->next();
@ -1600,7 +1603,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool&
if (start->strAt(-1) == "delete") if (start->strAt(-1) == "delete")
return(false); return(false);
tok1 = end; tok1 = jumpBackToken?jumpBackToken:end; // Jump back to first [ to check inside, or jump to end of expression
} }
// streaming: << // streaming: <<

View File

@ -163,6 +163,7 @@ private:
TEST_CASE(constIfCfg); // ticket #1881 - fp when there are #if TEST_CASE(constIfCfg); // ticket #1881 - fp when there are #if
TEST_CASE(constFriend); // ticket #1921 - fp for friend function TEST_CASE(constFriend); // ticket #1921 - fp for friend function
TEST_CASE(constUnion); // ticket #2111 - fp when there is a union TEST_CASE(constUnion); // ticket #2111 - fp when there is a union
TEST_CASE(constArrayOperator); // #4406
TEST_CASE(initializerListOrder); TEST_CASE(initializerListOrder);
TEST_CASE(initializerListUsage); TEST_CASE(initializerListUsage);
@ -5336,6 +5337,23 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void constArrayOperator() {
checkConst("struct foo {\n"
" int x;\n"
" int y[5][724];\n"
" T a() {\n"
" return y[x++][6];\n"
" }\n"
" T b() {\n"
" return y[1][++x];\n"
" }\n"
" T c() {\n"
" return y[1][6];\n"
" }\n"
"};");
ASSERT_EQUALS("[test.cpp:10]: (style, inconclusive) Technically the member function 'foo::c' can be const.\n", errout.str());
}
void checkInitializerListOrder(const char code[]) { void checkInitializerListOrder(const char code[]) {
// Clear the error log // Clear the error log
errout.str(""); errout.str("");