From abc3a57d4ac695146b43724202a52049d067b52c Mon Sep 17 00:00:00 2001 From: chrchr Date: Tue, 7 Mar 2023 18:04:22 +0100 Subject: [PATCH 1/5] Fix #11602 "debug: Executable scope 'x' with unknown function" --- lib/symboldatabase.cpp | 23 +++++++++++------ test/testsymboldatabase.cpp | 50 ++++++++++++++++++++++++------------- 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 4b3dc3199df..03b04eacc23 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%|::")) + 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(); + first = skipTopLevelConst(first); + const Token* old = second; + second = skipTopLevelConst(second); // skip default value assignment - else if (first->next()->str() == "=") { + if (old == second && first->next()->str() == "=") { first = first->nextArgument(); if (first) first = first->tokAt(-2); diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 587f085224d..33fc2da91d5 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -5138,23 +5138,39 @@ class TestSymbolDatabase : public TestFixture { 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()); + } + settings1.debugwarnings = oldDebug; } void createSymbolDatabaseFindAllScopes1() { From 65389e5fa6c818d18c49131582844be304472132 Mon Sep 17 00:00:00 2001 From: chrchr Date: Tue, 7 Mar 2023 18:45:05 +0100 Subject: [PATCH 2/5] Fix match --- lib/symboldatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 03b04eacc23..e513e3c4aac 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2687,7 +2687,7 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se const Token* tok = start->next(); if (Token::simpleMatch(tok, "const")) { tok = tok->next(); - while (Token::Match(tok, "%name%|::")) + while (Token::Match(tok, "%name%|%type%::")) tok = tok->next(); if (Token::Match(tok, ",|)")) return start->next(); From cabd78e16794f514338b830d33b7ed6dc5b0c0d3 Mon Sep 17 00:00:00 2001 From: chrchr Date: Tue, 7 Mar 2023 19:35:38 +0100 Subject: [PATCH 3/5] Typo --- lib/symboldatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index e513e3c4aac..e6ee8d6e452 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2687,7 +2687,7 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se const Token* tok = start->next(); if (Token::simpleMatch(tok, "const")) { tok = tok->next(); - while (Token::Match(tok, "%name%|%type%::")) + while (Token::Match(tok, "%name%|%type%|::")) tok = tok->next(); if (Token::Match(tok, ",|)")) return start->next(); From fbb2b3a9bb6812ec545945be97dfe07681784774 Mon Sep 17 00:00:00 2001 From: chrchr Date: Tue, 7 Mar 2023 20:15:30 +0100 Subject: [PATCH 4/5] Fix condition --- lib/symboldatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index e6ee8d6e452..574158663ce 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2735,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 (old == second && second->next()->str() == "=") { second = second->nextArgument(); if (second) second = second->tokAt(-2); From 86ffb016d04792cdd353f78c239f5f67f3df6878 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Tue, 7 Mar 2023 23:42:49 +0100 Subject: [PATCH 5/5] Handle default parameter value, add test --- lib/symboldatabase.cpp | 8 ++++---- test/testsymboldatabase.cpp | 8 ++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 574158663ce..401975a22ff 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2689,7 +2689,7 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se tok = tok->next(); while (Token::Match(tok, "%name%|%type%|::")) tok = tok->next(); - if (Token::Match(tok, ",|)")) + if (Token::Match(tok, ",|)|=")) return start->next(); } return start; @@ -2716,12 +2716,12 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se second = second->next(); // skip const on type passed by value + const Token* const oldSecond = second; first = skipTopLevelConst(first); - const Token* old = second; second = skipTopLevelConst(second); // skip default value assignment - if (old == second && first->next()->str() == "=") { + if (oldSecond == second && first->next()->str() == "=") { first = first->nextArgument(); if (first) first = first->tokAt(-2); @@ -2735,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 (old == second && 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 33fc2da91d5..214e631ceff 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -5170,6 +5170,14 @@ class TestSymbolDatabase : public TestFixture { 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; }