Fix #11596 FP uninitvar with array of function pointers (#5098)

This commit is contained in:
chrchr-github 2023-06-07 11:41:22 +02:00 committed by GitHub
parent 30aa0ae880
commit 39f958bcfb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 1 deletions

View File

@ -2202,8 +2202,11 @@ void Variable::evaluate(const Settings* settings)
{ {
// Is there initialization in variable declaration // Is there initialization in variable declaration
const Token *initTok = mNameToken ? mNameToken->next() : nullptr; const Token *initTok = mNameToken ? mNameToken->next() : nullptr;
while (initTok && initTok->str() == "[") while (Token::Match(initTok, "[|(")) {
initTok = initTok->link()->next(); initTok = initTok->link()->next();
if (Token::simpleMatch(initTok, ")"))
initTok = initTok->next();
}
if (Token::Match(initTok, "=|{") || (initTok && initTok->isSplittedVarDeclEq())) if (Token::Match(initTok, "=|{") || (initTok && initTok->isSplittedVarDeclEq()))
setFlag(fIsInit, true); setFlag(fIsInit, true);

View File

@ -3188,6 +3188,22 @@ private:
"};\n"); "};\n");
ASSERT_EQUALS("", errout.str()); 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<D*>(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<int*>&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 check("struct A {\n" // #11225
" A();\n" " A();\n"
" virtual ~A();\n" " virtual ~A();\n"

View File

@ -139,6 +139,7 @@ private:
TEST_CASE(test_isVariableDeclarationIdentifiesArray); TEST_CASE(test_isVariableDeclarationIdentifiesArray);
TEST_CASE(test_isVariableDeclarationIdentifiesPointerArray); TEST_CASE(test_isVariableDeclarationIdentifiesPointerArray);
TEST_CASE(test_isVariableDeclarationIdentifiesOfArrayPointers); TEST_CASE(test_isVariableDeclarationIdentifiesOfArrayPointers);
TEST_CASE(test_isVariableDeclarationIdentifiesArrayOfFunctionPointers);
TEST_CASE(isVariableDeclarationIdentifiesTemplatedPointerVariable); TEST_CASE(isVariableDeclarationIdentifiesTemplatedPointerVariable);
TEST_CASE(isVariableDeclarationIdentifiesTemplatedPointerToPointerVariable); TEST_CASE(isVariableDeclarationIdentifiesTemplatedPointerToPointerVariable);
TEST_CASE(isVariableDeclarationIdentifiesTemplatedArrayVariable); TEST_CASE(isVariableDeclarationIdentifiesTemplatedArrayVariable);
@ -877,6 +878,22 @@ private:
ASSERT(false == v.isReference()); 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() { void isVariableDeclarationIdentifiesTemplatedPointerVariable() {
reset(); reset();
GET_SYMBOL_DB("std::set<char>* chars;"); GET_SYMBOL_DB("std::set<char>* chars;");