diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 3225ef2cf..d1c0d3d33 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2243,7 +2243,7 @@ void Variable::evaluate(const Settings* settings) setFlag(fIsConst, true); setFlag(fIsStatic, true); } else if (tok->str() == "*") { - setFlag(fIsPointer, !isArray() || (isContainer && !Token::Match(tok->next(), "%name% [")) || Token::Match(tok->previous(), "( * %name% )")); + setFlag(fIsPointer, !isArray() || (isContainer && !Token::Match(tok->next(), "%name% [")) || Token::Match(tok, "* const| %name% )")); setFlag(fIsConst, false); // Points to const, isn't necessarily const itself } else if (tok->str() == "&") { if (isReference()) diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index aaf934775..b7ff49913 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -137,7 +137,9 @@ private: TEST_CASE(test_isVariableDeclarationIdentifiesDeclarationWithMultipleIndirection); TEST_CASE(test_isVariableDeclarationIdentifiesArray); TEST_CASE(test_isVariableDeclarationIdentifiesPointerArray); - TEST_CASE(test_isVariableDeclarationIdentifiesOfArrayPointers); + TEST_CASE(test_isVariableDeclarationIdentifiesOfArrayPointers1); + TEST_CASE(test_isVariableDeclarationIdentifiesOfArrayPointers2); + TEST_CASE(test_isVariableDeclarationIdentifiesOfArrayPointers3); TEST_CASE(test_isVariableDeclarationIdentifiesArrayOfFunctionPointers); TEST_CASE(isVariableDeclarationIdentifiesTemplatedPointerVariable); TEST_CASE(isVariableDeclarationIdentifiesTemplatedPointerToPointerVariable); @@ -872,7 +874,7 @@ private: ASSERT(false == v.isReference()); } - void test_isVariableDeclarationIdentifiesOfArrayPointers() { + void test_isVariableDeclarationIdentifiesOfArrayPointers1() { reset(); GET_SYMBOL_DB("A (*a)[5];"); const bool result = db->scopeList.front().isVariableDeclaration(tokenizer.tokens(), vartok, typetok); @@ -887,6 +889,36 @@ private: ASSERT(false == v.isReference()); } + void test_isVariableDeclarationIdentifiesOfArrayPointers2() { + reset(); + GET_SYMBOL_DB("A (*const a)[5];"); + const bool result = db->scopeList.front().isVariableDeclaration(tokenizer.tokens(), vartok, typetok); + ASSERT_EQUALS(true, result); + ASSERT_EQUALS("a", vartok->str()); + ASSERT_EQUALS("A", typetok->str()); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + ASSERT(true == v.isPointer()); + ASSERT(false == v.isArray()); + ASSERT(true == v.isPointerToArray()); + ASSERT(false == v.isPointerArray()); + ASSERT(false == v.isReference()); + } + + void test_isVariableDeclarationIdentifiesOfArrayPointers3() { + reset(); + GET_SYMBOL_DB("A (** a)[5];"); + const bool result = db->scopeList.front().isVariableDeclaration(tokenizer.tokens(), vartok, typetok); + ASSERT_EQUALS(true, result); + ASSERT_EQUALS("a", vartok->str()); + ASSERT_EQUALS("A", typetok->str()); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + ASSERT(true == v.isPointer()); + ASSERT(false == v.isArray()); + ASSERT(true == v.isPointerToArray()); + ASSERT(false == v.isPointerArray()); + ASSERT(false == v.isReference()); + } + void test_isVariableDeclarationIdentifiesArrayOfFunctionPointers() { reset(); GET_SYMBOL_DB("int (*a[])(int) = { g };"); // #11596