From c5310fe8a2796d492ffbb12c6cab51b355837778 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 22 Apr 2023 10:23:12 +0200 Subject: [PATCH] Fix #8592 SymbolDatabase: better handling of 'using namespace' (#4974) --- lib/symboldatabase.cpp | 14 +++++++++++++- test/testsymboldatabase.cpp | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 1dd760dca..362c9cdaa 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -5549,7 +5549,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const //--------------------------------------------------------------------------- -const Function* SymbolDatabase::findFunction(const Token *tok) const +const Function* SymbolDatabase::findFunction(const Token* const tok) const { // find the scope this function is in const Scope *currScope = tok->scope(); @@ -5665,6 +5665,18 @@ const Function* SymbolDatabase::findFunction(const Token *tok) const return func; currScope = currScope->nestedIn; } + // check using namespace + currScope = tok->scope(); + while (currScope) { + for (const auto& ul : currScope->usingList) { + if (ul.scope) { + const Function* func = ul.scope->findFunction(tok); + if (func) + return func; + } + } + currScope = currScope->nestedIn; + } } // Check for constructor if (Token::Match(tok, "%name% (|{")) { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index bdaae44fc..4f11dc312 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -444,6 +444,7 @@ private: TEST_CASE(findFunction45); TEST_CASE(findFunction46); TEST_CASE(findFunction47); + TEST_CASE(findFunction48); TEST_CASE(findFunctionContainer); TEST_CASE(findFunctionExternC); TEST_CASE(findFunctionGlobalScope); // ::foo @@ -7155,7 +7156,38 @@ private: ASSERT_EQUALS(3, functok->function()->tokenDef->linenr()); } - void findFunction47() { + void findFunction47() { // #8592 + { + GET_SYMBOL_DB("namespace N {\n" + " void toupper(std::string& str);\n" + "}\n" + "void f(std::string s) {\n" + " using namespace N;\n" + " toupper(s);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + const Token *functok = Token::findsimplematch(tokenizer.tokens(), "toupper ( s"); + ASSERT(functok && functok->function()); + ASSERT(functok->function()->name() == "toupper"); + ASSERT_EQUALS(2, functok->function()->tokenDef->linenr()); + } + { + GET_SYMBOL_DB("namespace N {\n" + " void toupper(std::string& str);\n" + "}\n" + "using namespace N;\n" + "void f(std::string s) {\n" + " toupper(s);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + const Token *functok = Token::findsimplematch(tokenizer.tokens(), "toupper ( s"); + ASSERT(functok && functok->function()); + ASSERT(functok->function()->name() == "toupper"); + ASSERT_EQUALS(2, functok->function()->tokenDef->linenr()); + } + } + + void findFunction48() { GET_SYMBOL_DB("struct S {\n" " S() {}\n" " std::list l;\n"