From 39f958bcfbb6752226c8c01a6119fdc4da5d9e71 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 7 Jun 2023 11:41:22 +0200 Subject: [PATCH] Fix #11596 FP uninitvar with array of function pointers (#5098) --- lib/symboldatabase.cpp | 5 ++++- test/testother.cpp | 16 ++++++++++++++++ test/testsymboldatabase.cpp | 17 +++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) 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;");