diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 5f431a9ba..dec2d9914 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1151,7 +1151,7 @@ void SymbolDatabase::createSymbolDatabaseSetVariablePointers() // Set Token::variable pointer for array member variable // Since it doesn't point at a fixed location it doesn't have varid if (tok->variable() != nullptr && - (tok->variable()->typeScope() || (tok->valueType() && tok->valueType()->type == ValueType::CONTAINER)) && + (tok->variable()->typeScope() || tok->variable()->isSmartPointer() || (tok->valueType() && tok->valueType()->type == ValueType::CONTAINER)) && Token::Match(tok, "%name% [|.")) { Token *tok2 = tok->next(); @@ -1174,6 +1174,13 @@ void SymbolDatabase::createSymbolDatabaseSetVariablePointers() if (membertok->varId() == 0 || mVariableList[membertok->varId()] == nullptr) fixVarId(varIds, tok, const_cast(membertok), membervar); } + } else if (const ::Type *type = var ? var->smartPointerType() : nullptr) { + const Variable *membervar = type->classScope->getVariable(membertok->str()); + if (membervar) { + membertok->variable(membervar); + if (membertok->varId() == 0 || mVariableList[membertok->varId()] == nullptr) + fixVarId(varIds, tok, const_cast(membertok), membervar); + } } else if (var && tok->valueType() && tok->valueType()->type == ValueType::CONTAINER) { if (Token::Match(var->typeStartToken(), "std :: %type% < %type% *| *| >")) { const Type * type = var->typeStartToken()->tokAt(4)->type(); @@ -1845,7 +1852,7 @@ const Type *Variable::smartPointerType() const while (Token::Match(ptrType, "%name%|::")) ptrType = ptrType->next(); if (Token::Match(ptrType, "< %name% >")) - return ptrType->next()->type(); + return ptrType->scope()->findType(ptrType->next()->str()); return nullptr; } diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 5d7e468d1..f9ad41596 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -351,6 +351,7 @@ private: TEST_CASE(findFunction26); // #8668 - pointer parameter in function call, const pointer function argument TEST_CASE(findFunction27); TEST_CASE(findFunction28); + TEST_CASE(findFunction29); TEST_CASE(findFunctionContainer); TEST_CASE(findFunctionExternC); TEST_CASE(findFunctionGlobalScope); // ::foo @@ -5737,6 +5738,27 @@ private: ASSERT_EQUALS(4, a->function()->token->linenr()); } + void findFunction29() { + GET_SYMBOL_DB("struct A {\n" + " int foo() const;\n" + "};\n" + "\n" + "struct B {\n" + " A a;\n" + "};\n" + "\n" + "typedef std::shared_ptr BPtr;\n" + "\n" + "void bar(BPtr b) {\n" + " int x = b->a.foo();\n" + "}"); + const Token *foo = Token::findsimplematch(tokenizer.tokens(), "foo ( ) ;"); + ASSERT(foo); + ASSERT(foo->function()); + ASSERT(foo->function()->token); + ASSERT_EQUALS(2, foo->function()->token->linenr()); + } + void findFunctionContainer() { { GET_SYMBOL_DB("void dostuff(std::vector v);\n"