From b6e93bb5758a178cfc1f74038e6e71378bd1f364 Mon Sep 17 00:00:00 2001 From: IOBYTE Date: Thu, 11 Feb 2021 02:08:45 -0500 Subject: [PATCH] fix #10172 (debug: Executable scope 'x' with unknown function.) (#3121) --- lib/tokenize.cpp | 26 ++++++++++++++- test/testsimplifyusing.cpp | 67 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index cc97f836e..f9a08c023 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1808,6 +1808,22 @@ namespace { } } + const ScopeInfo3 * findScopeRecursive(const std::string & scope) const { + if (fullName.size() < scope.size() && + fullName == scope.substr(0, fullName.size())) { + for (auto & child : children) { + if (child.fullName == scope && &child != this) + return &child; + else { + const ScopeInfo3 * temp1 = child.findScopeRecursive(scope); + if (temp1) + return temp1; + } + } + } + return nullptr; + } + const ScopeInfo3 * findScope(const std::string & scope) const { const ScopeInfo3 * tempScope = this; while (tempScope) { @@ -1815,9 +1831,17 @@ namespace { if (child.type == Record && (child.name == scope || child.fullName == scope)) return &child; } - tempScope = tempScope->parent; } + // check for another scope with same name + const ScopeInfo3 * global = this; + while (global->parent) + global = global->parent; + for (const ScopeInfo3 & tempChild : global->children) { + const ScopeInfo3 * temp = tempChild.findScopeRecursive(scope); + if (temp) + return temp; + } return nullptr; } diff --git a/test/testsimplifyusing.cpp b/test/testsimplifyusing.cpp index 394ae2668..1fa867532 100644 --- a/test/testsimplifyusing.cpp +++ b/test/testsimplifyusing.cpp @@ -80,6 +80,7 @@ private: TEST_CASE(simplifyUsing10054); TEST_CASE(simplifyUsing10136); TEST_CASE(simplifyUsing10171); + TEST_CASE(simplifyUsing10172); } std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Native, bool debugwarnings = true) { @@ -1032,6 +1033,72 @@ private: "void B :: f ( const std :: vector < unsigned char > & ) const { } " "}"; ASSERT_EQUALS(exp, tok(code, false)); + ASSERT_EQUALS("", errout.str()); + } + + void simplifyUsing10172() { + { + const char code[] = "namespace ns {\n" + " class A {\n" + " public:\n" + " using h = std::function;\n" + " };\n" + " class B : public A {\n" + " void f(h);\n" + " };\n" + "}\n" + "namespace ns {\n" + " void B::f(h) { }\n" + "}"; + const char exp[] = "namespace ns { " + "class A { " + "public: " + "} ; " + "class B : public A { " + "void f ( std :: function < void ( ) > ) ; " + "} ; " + "} " + "namespace ns { " + "void B :: f ( std :: function < void ( ) > ) { } " + "}"; + ASSERT_EQUALS(exp, tok(code, false)); + ASSERT_EQUALS("", errout.str()); + } + { + const char code[] = "namespace ns {\n" + "namespace external {\n" + "class A {\n" + "public: \n" + " using h = std::function;\n" + "};\n" + "class B : public A {\n" + " void f(h);\n" + "};\n" + "}\n" + "}\n" + "namespace ns {\n" + "namespace external {\n" + "void B::f(h) {}\n" + "}\n" + "}"; + const char exp[] = "namespace ns { " + "namespace external { " + "class A { " + "public: " + "} ; " + "class B : public A { " + "void f ( std :: function < void ( ) > ) ; " + "} ; " + "} " + "} " + "namespace ns { " + "namespace external { " + "void B :: f ( std :: function < void ( ) > ) { } " + "} " + "}"; + ASSERT_EQUALS(exp, tok(code, false)); + ASSERT_EQUALS("", errout.str()); + } } };