fix #10122, #10124 and #10125 (debug: Executable scope 'x' with unknown function.) (#3073)

This commit is contained in:
IOBYTE 2021-01-21 13:47:51 -05:00 committed by GitHub
parent 6f49a2ff4a
commit d39956414f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 5 deletions

View File

@ -2371,8 +2371,8 @@ static bool typesMatch(
tok2 = tok2->next(); tok2 = tok2->next();
// update parser token positions // update parser token positions
if (tok1 && tok2) { if (tok1 && tok2) {
*new_first = tok1; *new_first = tok1->previous();
*new_second = tok2; *new_second = tok2->previous();
return true; return true;
} }
} }

View File

@ -561,8 +561,11 @@ void Tokenizer::simplifyUsingToTypedef()
{ {
for (Token *tok = list.front(); tok; tok = tok->next()) { for (Token *tok = list.front(); tok; tok = tok->next()) {
// using a::b; => typedef a::b b; // using a::b; => typedef a::b b;
if (Token::Match(tok, "[;{}] using %name% :: %name% ::|;") && !tok->tokAt(2)->isKeyword()) { if ((Token::Match(tok, "[;{}] using %name% :: %name% ::|;") && !tok->tokAt(2)->isKeyword()) ||
Token *endtok = tok->tokAt(5); (Token::Match(tok, "[;{}] using :: %name% :: %name% ::|;") && !tok->tokAt(3)->isKeyword())) {
Token *endtok = tok->tokAt(5);
if (Token::Match(endtok, "%name%"))
endtok = endtok->next();
while (Token::Match(endtok, ":: %name%")) while (Token::Match(endtok, ":: %name%"))
endtok = endtok->tokAt(2); endtok = endtok->tokAt(2);
if (endtok && endtok->str() == ";") { if (endtok && endtok->str() == ";") {
@ -1904,7 +1907,7 @@ namespace {
std::string::size_type index = scope.size(); std::string::size_type index = scope.size();
std::string::size_type new_index = std::string::npos; std::string::size_type new_index = std::string::npos;
bool match = true; bool match = true;
while (tok2->strAt(-1) == "::") { while (Token::Match(tok2->tokAt(-2), "%name% ::") && !tok2->tokAt(-2)->isKeyword()) {
std::string last; std::string last;
if (match && !scope1.empty()) { if (match && !scope1.empty()) {
new_index = scope1.rfind(' ', index - 1); new_index = scope1.rfind(' ', index - 1);

View File

@ -400,6 +400,9 @@ private:
TEST_CASE(findFunction33); // #9885 variadic function TEST_CASE(findFunction33); // #9885 variadic function
TEST_CASE(findFunction34); // #10061 TEST_CASE(findFunction34); // #10061
TEST_CASE(findFunction35); TEST_CASE(findFunction35);
TEST_CASE(findFunction36); // #10122
TEST_CASE(findFunction37); // #10124
TEST_CASE(findFunction38); // #10152
TEST_CASE(findFunctionContainer); TEST_CASE(findFunctionContainer);
TEST_CASE(findFunctionExternC); TEST_CASE(findFunctionExternC);
TEST_CASE(findFunctionGlobalScope); // ::foo TEST_CASE(findFunctionGlobalScope); // ::foo
@ -6262,6 +6265,63 @@ private:
ASSERT_EQUALS(5, foo->function()->tokenDef->linenr()); ASSERT_EQUALS(5, foo->function()->tokenDef->linenr());
} }
void findFunction36() { // #10122
GET_SYMBOL_DB("namespace external {\n"
" enum class T { };\n"
"}\n"
"namespace ns {\n"
" class A {\n"
" public:\n"
" void f(external::T);\n"
" };\n"
"}\n"
"namespace ns {\n"
" void A::f(external::T link_type) { }\n"
"}");
ASSERT_EQUALS("", errout.str());
const Token *functok = Token::findsimplematch(tokenizer.tokens(), "f ( external :: T link_type )");
ASSERT(functok);
ASSERT(functok->function());
ASSERT(functok->function()->name() == "f");
ASSERT_EQUALS(7, functok->function()->tokenDef->linenr());
}
void findFunction37() { // #10124
GET_SYMBOL_DB("namespace ns {\n"
" class V { };\n"
"}\n"
"class A {\n"
"public:\n"
" void f(const ns::V&);\n"
"};\n"
"using ::ns::V;\n"
"void A::f(const V&) { }");
ASSERT_EQUALS("", errout.str());
const Token *functok = Token::findsimplematch(tokenizer.tokens(), "f ( const :: ns :: V & )");
ASSERT(functok);
ASSERT(functok->function());
ASSERT(functok->function()->name() == "f");
ASSERT_EQUALS(6, functok->function()->tokenDef->linenr());
}
void findFunction38() { // #10125
GET_SYMBOL_DB("namespace ns {\n"
" class V { };\n"
" using Var = V;\n"
"}\n"
"class A {\n"
" void f(const ns::Var&);\n"
"};\n"
"using ::ns::Var;\n"
"void A::f(const Var&) {}");
ASSERT_EQUALS("", errout.str());
const Token *functok = Token::findsimplematch(tokenizer.tokens(), "f ( const :: ns :: V & )");
ASSERT(functok);
ASSERT(functok->function());
ASSERT(functok->function()->name() == "f");
ASSERT_EQUALS(6, functok->function()->tokenDef->linenr());
}
void findFunctionContainer() { void findFunctionContainer() {
{ {
GET_SYMBOL_DB("void dostuff(std::vector<int> v);\n" GET_SYMBOL_DB("void dostuff(std::vector<int> v);\n"