diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 9af7e54f4..febcea819 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2202,8 +2202,11 @@ void Variable::evaluate(const Settings* settings) { // Is there initialization in variable declaration const Token *initTok = mNameToken ? mNameToken->next() : nullptr; - while (initTok && initTok->str() == "[") + while (Token::Match(initTok, "[|(")) { initTok = initTok->link()->next(); + if (Token::simpleMatch(initTok, ")")) + initTok = initTok->next(); + } if (Token::Match(initTok, "=|{") || (initTok && initTok->isSplittedVarDeclEq())) setFlag(fIsInit, true); diff --git a/test/testother.cpp b/test/testother.cpp index cb15ac2e2..6dbf1842c 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -3188,6 +3188,22 @@ private: "};\n"); ASSERT_EQUALS("", errout.str()); + check("struct B { virtual void f() const {} };\n" // #11528 + "struct D : B {};\n" + "void g(B* b) {\n" + " D* d = dynamic_cast(b);\n" + " if (d)\n" + " d->f();\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'd' can be declared as pointer to const\n", errout.str()); + + check("void g(const int*);\n" + "void f(const std::vector&v) {\n" + " for (int* i : v)\n" + " g(i);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' can be declared as pointer to const\n", errout.str()); + check("struct A {\n" // #11225 " A();\n" " virtual ~A();\n" diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 44b2d21f9..c0f8edcbc 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -139,6 +139,7 @@ private: TEST_CASE(test_isVariableDeclarationIdentifiesArray); TEST_CASE(test_isVariableDeclarationIdentifiesPointerArray); TEST_CASE(test_isVariableDeclarationIdentifiesOfArrayPointers); + TEST_CASE(test_isVariableDeclarationIdentifiesArrayOfFunctionPointers); TEST_CASE(isVariableDeclarationIdentifiesTemplatedPointerVariable); TEST_CASE(isVariableDeclarationIdentifiesTemplatedPointerToPointerVariable); TEST_CASE(isVariableDeclarationIdentifiesTemplatedArrayVariable); @@ -877,6 +878,22 @@ private: ASSERT(false == v.isReference()); } + void test_isVariableDeclarationIdentifiesArrayOfFunctionPointers() { + reset(); + GET_SYMBOL_DB("int (*a[])(int) = { g };"); // #11596 + const bool result = db->scopeList.front().isVariableDeclaration(tokenizer.tokens(), vartok, typetok); + ASSERT_EQUALS(true, result); + ASSERT_EQUALS("a", vartok->str()); + ASSERT_EQUALS("int", typetok->str()); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + ASSERT(false == v.isPointer()); + ASSERT(true == v.isArray()); + ASSERT(false == v.isPointerToArray()); + ASSERT(true == v.isPointerArray()); + ASSERT(false == v.isReference()); + ASSERT(true == v.isInit()); + } + void isVariableDeclarationIdentifiesTemplatedPointerVariable() { reset(); GET_SYMBOL_DB("std::set* chars;");