diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 0fc60766329..99cede92bfe 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1510,6 +1510,16 @@ void SymbolDatabase::createSymbolDatabaseIncompleteVars() continue; if (mSettings.standards.cpp >= Standards::CPP20 && cpp20keywords.count(tok->str()) > 0) continue; + std::string fstr = tok->str(); + const Token* ftok = tok->previous(); + while (Token::simpleMatch(ftok, "::")) { + if (!Token::Match(ftok->previous(), "%name%")) + break; + fstr.insert(0, ftok->previous()->str() + "::"); + ftok = ftok->tokAt(-2); + } + if (mSettings.library.functions.find(fstr) != mSettings.library.functions.end()) + continue; const_cast(tok)->isIncompleteVar(true); // TODO: avoid const_cast } } diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 46167ec548f..8fab8b21fac 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -5464,6 +5464,21 @@ class TestSymbolDatabase : public TestFixture { const Token* s4 = Token::findsimplematch(s3->next(), "string )"); ASSERT(s4 && !s4->isIncompleteVar()); } + { + GET_SYMBOL_DB("void destroy(int*, void (*cb_dealloc)(void *));\n" + "void f(int* p, int* q, int* r) {\n" + " destroy(p, free);\n" + " destroy(q, std::free);\n" + " destroy(r, N::free);\n" + "}\n"); + ASSERT(db && errout.str().empty()); + const Token* free1 = Token::findsimplematch(tokenizer.tokens(), "free"); + ASSERT(free1 && !free1->isIncompleteVar()); + const Token* free2 = Token::findsimplematch(free1->next(), "free"); + ASSERT(free2 && !free2->isIncompleteVar()); + const Token* free3 = Token::findsimplematch(free2->next(), "free"); + ASSERT(free3 && free3->isIncompleteVar()); + } } void enum1() {