Skip to content

Commit d399564

Browse files
authored
fix #10122, #10124 and #10125 (debug: Executable scope 'x' with unknown function.) (#3073)
1 parent 6f49a2f commit d399564

3 files changed

Lines changed: 68 additions & 5 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2371,8 +2371,8 @@ static bool typesMatch(
23712371
tok2 = tok2->next();
23722372
// update parser token positions
23732373
if (tok1 && tok2) {
2374-
*new_first = tok1;
2375-
*new_second = tok2;
2374+
*new_first = tok1->previous();
2375+
*new_second = tok2->previous();
23762376
return true;
23772377
}
23782378
}

lib/tokenize.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,11 @@ void Tokenizer::simplifyUsingToTypedef()
561561
{
562562
for (Token *tok = list.front(); tok; tok = tok->next()) {
563563
// using a::b; => typedef a::b b;
564-
if (Token::Match(tok, "[;{}] using %name% :: %name% ::|;") && !tok->tokAt(2)->isKeyword()) {
565-
Token *endtok = tok->tokAt(5);
564+
if ((Token::Match(tok, "[;{}] using %name% :: %name% ::|;") && !tok->tokAt(2)->isKeyword()) ||
565+
(Token::Match(tok, "[;{}] using :: %name% :: %name% ::|;") && !tok->tokAt(3)->isKeyword())) {
566+
Token *endtok = tok->tokAt(5);
567+
if (Token::Match(endtok, "%name%"))
568+
endtok = endtok->next();
566569
while (Token::Match(endtok, ":: %name%"))
567570
endtok = endtok->tokAt(2);
568571
if (endtok && endtok->str() == ";") {
@@ -1904,7 +1907,7 @@ namespace {
19041907
std::string::size_type index = scope.size();
19051908
std::string::size_type new_index = std::string::npos;
19061909
bool match = true;
1907-
while (tok2->strAt(-1) == "::") {
1910+
while (Token::Match(tok2->tokAt(-2), "%name% ::") && !tok2->tokAt(-2)->isKeyword()) {
19081911
std::string last;
19091912
if (match && !scope1.empty()) {
19101913
new_index = scope1.rfind(' ', index - 1);

test/testsymboldatabase.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,9 @@ class TestSymbolDatabase: public TestFixture {
400400
TEST_CASE(findFunction33); // #9885 variadic function
401401
TEST_CASE(findFunction34); // #10061
402402
TEST_CASE(findFunction35);
403+
TEST_CASE(findFunction36); // #10122
404+
TEST_CASE(findFunction37); // #10124
405+
TEST_CASE(findFunction38); // #10152
403406
TEST_CASE(findFunctionContainer);
404407
TEST_CASE(findFunctionExternC);
405408
TEST_CASE(findFunctionGlobalScope); // ::foo
@@ -6262,6 +6265,63 @@ class TestSymbolDatabase: public TestFixture {
62626265
ASSERT_EQUALS(5, foo->function()->tokenDef->linenr());
62636266
}
62646267

6268+
void findFunction36() { // #10122
6269+
GET_SYMBOL_DB("namespace external {\n"
6270+
" enum class T { };\n"
6271+
"}\n"
6272+
"namespace ns {\n"
6273+
" class A {\n"
6274+
" public:\n"
6275+
" void f(external::T);\n"
6276+
" };\n"
6277+
"}\n"
6278+
"namespace ns {\n"
6279+
" void A::f(external::T link_type) { }\n"
6280+
"}");
6281+
ASSERT_EQUALS("", errout.str());
6282+
const Token *functok = Token::findsimplematch(tokenizer.tokens(), "f ( external :: T link_type )");
6283+
ASSERT(functok);
6284+
ASSERT(functok->function());
6285+
ASSERT(functok->function()->name() == "f");
6286+
ASSERT_EQUALS(7, functok->function()->tokenDef->linenr());
6287+
}
6288+
6289+
void findFunction37() { // #10124
6290+
GET_SYMBOL_DB("namespace ns {\n"
6291+
" class V { };\n"
6292+
"}\n"
6293+
"class A {\n"
6294+
"public:\n"
6295+
" void f(const ns::V&);\n"
6296+
"};\n"
6297+
"using ::ns::V;\n"
6298+
"void A::f(const V&) { }");
6299+
ASSERT_EQUALS("", errout.str());
6300+
const Token *functok = Token::findsimplematch(tokenizer.tokens(), "f ( const :: ns :: V & )");
6301+
ASSERT(functok);
6302+
ASSERT(functok->function());
6303+
ASSERT(functok->function()->name() == "f");
6304+
ASSERT_EQUALS(6, functok->function()->tokenDef->linenr());
6305+
}
6306+
6307+
void findFunction38() { // #10125
6308+
GET_SYMBOL_DB("namespace ns {\n"
6309+
" class V { };\n"
6310+
" using Var = V;\n"
6311+
"}\n"
6312+
"class A {\n"
6313+
" void f(const ns::Var&);\n"
6314+
"};\n"
6315+
"using ::ns::Var;\n"
6316+
"void A::f(const Var&) {}");
6317+
ASSERT_EQUALS("", errout.str());
6318+
const Token *functok = Token::findsimplematch(tokenizer.tokens(), "f ( const :: ns :: V & )");
6319+
ASSERT(functok);
6320+
ASSERT(functok->function());
6321+
ASSERT(functok->function()->name() == "f");
6322+
ASSERT_EQUALS(6, functok->function()->tokenDef->linenr());
6323+
}
6324+
62656325
void findFunctionContainer() {
62666326
{
62676327
GET_SYMBOL_DB("void dostuff(std::vector<int> v);\n"

0 commit comments

Comments
 (0)