From d822de01bad6d427a0961463649ee48377756e38 Mon Sep 17 00:00:00 2001 From: Oleksandr Labetskyi Date: Mon, 12 Feb 2024 19:06:01 +0200 Subject: [PATCH 1/4] Fix --- lib/symboldatabase.cpp | 11 +++++++---- test/testsymboldatabase.cpp | 16 +++++++++++++++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 715c1c320e5..cb1dff605c6 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -737,7 +737,12 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() } else { tok = tok->link(); } - } else if (Token::Match(tok, "%name% (")) { + } else if (Token::Match(tok, "extern %type%")) { + while (Token::Match(tok, "%name%|*|&")) + tok = tok->next(); + if (tok->str() != "(") + continue; + tok = tok->previous(); if (Token::simpleMatch(tok->linkAt(1), ") ;")) { const Token *funcStart = nullptr; const Token *argStart = nullptr; @@ -760,7 +765,6 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() tok = declEnd; } } - continue; } } } @@ -5930,8 +5934,7 @@ const Function* SymbolDatabase::findFunction(const Token* const tok) const const Scope *currScope = tok->scope(); while (currScope && currScope->isExecutable()) { if (const Function* f = currScope->findFunction(tok)) { - if (f->isExtern()) - return f; + return f; } if (currScope->functionOf) currScope = currScope->functionOf; diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 7a4c7622b0c..c9ba5e235b5 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -270,7 +270,8 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(memberFunctionOfUnknownClassMacro2); TEST_CASE(memberFunctionOfUnknownClassMacro3); TEST_CASE(functionLinkage); - TEST_CASE(externalFunctionsInsideAFunction); // #12420 + TEST_CASE(externalFunctionsInsideAFunction); // #12420 + TEST_CASE(namespacedFunctionInsideExternBlock); // #12420 TEST_CASE(classWithFriend); @@ -2378,6 +2379,19 @@ class TestSymbolDatabase : public TestFixture { ASSERT(call && call->function() == f->function()); } + void namespacedFunctionInsideExternBlock() { + GET_SYMBOL_DB("namespace N {\n" + " void f();\n" + "}\n" + "extern \"C\" {\n" + " void f() {\n" + " N::f();\n" + " }\n" + "}\n"); + + ASSERT(db && errout.str().empty()); + } + void classWithFriend() { GET_SYMBOL_DB("class Foo {}; class Bar1 { friend class Foo; }; class Bar2 { friend Foo; };"); // 3 scopes: Global, 3 classes From 4793471f130889af140f8ed41f07b885b4d7df66 Mon Sep 17 00:00:00 2001 From: Oleksandr Labetskyi Date: Mon, 12 Feb 2024 19:23:23 +0200 Subject: [PATCH 2/4] Small fix --- lib/symboldatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index cb1dff605c6..d9f736d4702 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -740,7 +740,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() } else if (Token::Match(tok, "extern %type%")) { while (Token::Match(tok, "%name%|*|&")) tok = tok->next(); - if (tok->str() != "(") + if (!tok || tok->str() != "(") continue; tok = tok->previous(); if (Token::simpleMatch(tok->linkAt(1), ") ;")) { From 0aff3fbdcedf8dfe366e369ac8a06261140ab83c Mon Sep 17 00:00:00 2001 From: Oleksandr Labetskyi Date: Tue, 13 Feb 2024 00:17:45 +0200 Subject: [PATCH 3/4] Small fix --- lib/symboldatabase.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index d9f736d4702..e7b29684de5 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -738,19 +738,20 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() tok = tok->link(); } } else if (Token::Match(tok, "extern %type%")) { - while (Token::Match(tok, "%name%|*|&")) - tok = tok->next(); - if (!tok || tok->str() != "(") + const Token * ftok = tok->next(); + while (Token::Match(ftok, "%name%|*|&")) + ftok = ftok->next(); + if (!ftok || ftok->str() != "(") continue; - tok = tok->previous(); - if (Token::simpleMatch(tok->linkAt(1), ") ;")) { + ftok = ftok->previous(); + if (Token::simpleMatch(ftok->linkAt(1), ") ;")) { const Token *funcStart = nullptr; const Token *argStart = nullptr; const Token *declEnd = nullptr; - if (isFunction(tok, scope, &funcStart, &argStart, &declEnd)) { + if (isFunction(ftok, scope, &funcStart, &argStart, &declEnd)) { if (declEnd && declEnd->str() == ";") { bool newFunc = true; // Is this function already in the database? - auto range = scope->functionMap.equal_range(tok->str()); + auto range = scope->functionMap.equal_range(ftok->str()); for (std::multimap::const_iterator it = range.first; it != range.second; ++it) { if (it->second->argsMatch(scope, it->second->argDef, argStart, emptyString, 0)) { newFunc = false; @@ -759,7 +760,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() } // save function prototype in database if (newFunc) { - Function function(tok, scope, funcStart, argStart); + Function function(ftok, scope, funcStart, argStart); if (function.isExtern()) { scope->addFunction(std::move(function)); tok = declEnd; From 443e45d975821c22aa05c7272e0ada53a4376dce Mon Sep 17 00:00:00 2001 From: Oleksandr Labetskyi Date: Tue, 13 Feb 2024 10:27:12 +0200 Subject: [PATCH 4/4] Small nit --- test/testsymboldatabase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index c9ba5e235b5..1c42d76fdf9 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -2380,6 +2380,7 @@ class TestSymbolDatabase : public TestFixture { } void namespacedFunctionInsideExternBlock() { + // Should not crash GET_SYMBOL_DB("namespace N {\n" " void f();\n" "}\n"