Fix #8592 SymbolDatabase: better handling of 'using namespace' (#4974)

This commit is contained in:
chrchr-github 2023-04-22 10:23:12 +02:00 committed by GitHub
parent db955a13a9
commit c5310fe8a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 2 deletions

View File

@ -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 // find the scope this function is in
const Scope *currScope = tok->scope(); const Scope *currScope = tok->scope();
@ -5665,6 +5665,18 @@ const Function* SymbolDatabase::findFunction(const Token *tok) const
return func; return func;
currScope = currScope->nestedIn; 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 // Check for constructor
if (Token::Match(tok, "%name% (|{")) { if (Token::Match(tok, "%name% (|{")) {

View File

@ -444,6 +444,7 @@ private:
TEST_CASE(findFunction45); TEST_CASE(findFunction45);
TEST_CASE(findFunction46); TEST_CASE(findFunction46);
TEST_CASE(findFunction47); TEST_CASE(findFunction47);
TEST_CASE(findFunction48);
TEST_CASE(findFunctionContainer); TEST_CASE(findFunctionContainer);
TEST_CASE(findFunctionExternC); TEST_CASE(findFunctionExternC);
TEST_CASE(findFunctionGlobalScope); // ::foo TEST_CASE(findFunctionGlobalScope); // ::foo
@ -7155,7 +7156,38 @@ private:
ASSERT_EQUALS(3, functok->function()->tokenDef->linenr()); 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" GET_SYMBOL_DB("struct S {\n"
" S() {}\n" " S() {}\n"
" std::list<S> l;\n" " std::list<S> l;\n"