From 49c5a5aabdc5b65322c607c11bd40c70659a0531 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 9 Mar 2023 20:04:55 +0100 Subject: [PATCH] Fix #11602 "debug: Executable scope 'x' with unknown function" (#4869) --- lib/symboldatabase.cpp | 25 +++++++++++----- test/testsymboldatabase.cpp | 58 ++++++++++++++++++++++++++----------- 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 5bcb0c6c5..b93c7c67e 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2683,6 +2683,18 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se (Token::simpleMatch(first, "( void )") && Token::simpleMatch(second, "( )"))) return true; + auto skipTopLevelConst = [](const Token* start) -> const Token* { + const Token* tok = start->next(); + if (Token::simpleMatch(tok, "const")) { + tok = tok->next(); + while (Token::Match(tok, "%name%|%type%|::")) + tok = tok->next(); + if (Token::Match(tok, ",|)|=")) + return start->next(); + } + return start; + }; + while (first->str() == second->str() && first->isLong() == second->isLong() && first->isUnsigned() == second->isUnsigned()) { @@ -2704,15 +2716,12 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se second = second->next(); // skip const on type passed by value - if (Token::Match(first->next(), "const %type% %name%|,|)") && - !Token::Match(first->next(), "const %type% %name%| [")) - first = first->next(); - if (Token::Match(second->next(), "const %type% %name%|,|)") && - !Token::Match(second->next(), "const %type% %name%| [")) - second = second->next(); + const Token* const oldSecond = second; + first = skipTopLevelConst(first); + second = skipTopLevelConst(second); // skip default value assignment - else if (first->next()->str() == "=") { + if (oldSecond == second && first->next()->str() == "=") { first = first->nextArgument(); if (first) first = first->tokAt(-2); @@ -2726,7 +2735,7 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se } else if (!first) { // End of argument list (first) return !second->nextArgument(); // End of argument list (second) } - } else if (second->next()->str() == "=") { + } else if (oldSecond == second && second->next()->str() == "=") { second = second->nextArgument(); if (second) second = second->tokAt(-2); diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 59a294e2d..47a21e319 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -5138,23 +5138,47 @@ private: ASSERT_EQUALS("", errout.str()); } - void symboldatabase104() { // #11535 - GET_SYMBOL_DB("struct S {\n" - " void f1(char* const c);\n" - " void f2(char* const c);\n" - " void f3(char* const);\n" - " void f4(char* c);\n" - " void f5(char* c);\n" - " void f6(char*);\n" - "};\n" - "void S::f1(char* c) {}\n" - "void S::f2(char*) {}\n" - "void S::f3(char* c) {}\n" - "void S::f4(char* const c) {}\n" - "void S::f5(char* const) {}\n" - "void S::f6(char* const c) {}\n"); - ASSERT(db != nullptr); - ASSERT_EQUALS("", errout.str()); + void symboldatabase104() { + const bool oldDebug = settings1.debugwarnings; + settings1.debugwarnings = true; + { + GET_SYMBOL_DB("struct S {\n" // #11535 + " void f1(char* const c);\n" + " void f2(char* const c);\n" + " void f3(char* const);\n" + " void f4(char* c);\n" + " void f5(char* c);\n" + " void f6(char*);\n" + "};\n" + "void S::f1(char* c) {}\n" + "void S::f2(char*) {}\n" + "void S::f3(char* c) {}\n" + "void S::f4(char* const c) {}\n" + "void S::f5(char* const) {}\n" + "void S::f6(char* const c) {}\n"); + ASSERT(db != nullptr); + ASSERT_EQUALS("", errout.str()); + } + { + GET_SYMBOL_DB("struct S2 {\n" // #11602 + " enum E {};\n" + "};\n" + "struct S1 {\n" + " void f(S2::E) const;\n" + "};\n" + "void S1::f(const S2::E) const {}\n"); + ASSERT(db != nullptr); + ASSERT_EQUALS("", errout.str()); + } + { + GET_SYMBOL_DB("struct S {\n" + " void f(const bool b = false);\n" + "};\n" + "void S::f(const bool b) {}\n"); + ASSERT(db != nullptr); + ASSERT_EQUALS("", errout.str()); + } + settings1.debugwarnings = oldDebug; } void createSymbolDatabaseFindAllScopes1() {