From ecdfe51d428b8604fb604d780ca73dac246bf6a0 Mon Sep 17 00:00:00 2001 From: chrchr Date: Tue, 30 May 2023 19:11:08 +0200 Subject: [PATCH 1/3] Fix #11596 FP uninitvar with array of function pointers --- lib/symboldatabase.cpp | 5 ++++- test/testsymboldatabase.cpp | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index ef239d2c5e2..fccdcc3c012 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2175,8 +2175,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/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 44b2d21f996..c0f8edcbc3f 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -139,6 +139,7 @@ class TestSymbolDatabase : public TestFixture { 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 @@ class TestSymbolDatabase : public TestFixture { 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;"); From 1c99d42f6435fc1e5e0824111617ea6480b24bb7 Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 31 May 2023 14:30:11 +0200 Subject: [PATCH 2/3] Add test for #11528 --- test/testother.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/testother.cpp b/test/testother.cpp index 5b23e951f89..ed4a389cf75 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -3173,6 +3173,15 @@ class TestOther : public TestFixture { " }\n" "};\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()); } void constParameterCallback() { From 9011f5624c67245014754e720d5497aab7197bd4 Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 31 May 2023 14:35:03 +0200 Subject: [PATCH 3/3] Add test for #11445 --- test/testother.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/testother.cpp b/test/testother.cpp index ed4a389cf75..6aff34a0ae0 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -3182,6 +3182,13 @@ class TestOther : public TestFixture { " 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()); } void constParameterCallback() {