From d3087602a1e497bbd10f90defe0f859c5e313d69 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Sat, 16 Feb 2013 02:20:18 -0800 Subject: [PATCH] Fixed false positive "function can be const" if a non-const expression is inside []-brackets (#4406) --- lib/checkclass.cpp | 5 ++++- test/testclass.cpp | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index ed2cf6df5..b512e0e0d 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -1546,6 +1546,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool& if (tok1->str() == "this" && tok1->previous()->isAssignmentOp()) return(false); + const Token* jumpBackToken = 0; const Token *lastVarTok = tok1; const Token *end = tok1; 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 return(false); } + if (!jumpBackToken) + jumpBackToken = end->next(); // Check inside the [] brackets end = end->linkAt(1); } else if (end->strAt(1) == ")") end = end->next(); @@ -1600,7 +1603,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool& if (start->strAt(-1) == "delete") return(false); - tok1 = end; + tok1 = jumpBackToken?jumpBackToken:end; // Jump back to first [ to check inside, or jump to end of expression } // streaming: << diff --git a/test/testclass.cpp b/test/testclass.cpp index 68403862e..3231a470b 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -163,6 +163,7 @@ private: TEST_CASE(constIfCfg); // ticket #1881 - fp when there are #if 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(initializerListOrder); TEST_CASE(initializerListUsage); @@ -5336,6 +5337,23 @@ private: 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[]) { // Clear the error log errout.str("");