Skip to content

Commit 1872725

Browse files
authored
fix #10171 (debug: Executable scope 'x' with unknown function.) (cppcheck-opensource#3116)
1 parent 332c59d commit 1872725

2 files changed

Lines changed: 61 additions & 3 deletions

File tree

lib/tokenize.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1750,9 +1750,11 @@ namespace {
17501750
ScopeInfo3() : parent(nullptr), type(Global), bodyStart(nullptr), bodyEnd(nullptr) {}
17511751
ScopeInfo3(ScopeInfo3 *parent_, Type type_, const std::string &name_, const Token *bodyStart_, const Token *bodyEnd_)
17521752
: parent(parent_), type(type_), name(name_), bodyStart(bodyStart_), bodyEnd(bodyEnd_) {
1753+
if (name.empty())
1754+
return;
17531755
fullName = name;
17541756
ScopeInfo3 *scope = parent;
1755-
while (!fullName.empty() && scope && scope->parent) {
1757+
while (scope && scope->parent) {
17561758
fullName = scope->name + " :: " + fullName;
17571759
scope = scope->parent;
17581760
}
@@ -1806,9 +1808,31 @@ namespace {
18061808
}
18071809
}
18081810

1811+
const ScopeInfo3 * findScope(const std::string & scope) const {
1812+
const ScopeInfo3 * tempScope = this;
1813+
while (tempScope) {
1814+
for (const auto & child : tempScope->children) {
1815+
if (child.name == scope || child.fullName == scope)
1816+
return &child;
1817+
}
1818+
1819+
tempScope = tempScope->parent;
1820+
}
1821+
return nullptr;
1822+
}
1823+
18091824
bool findTypeInBase(const std::string &scope) const {
1825+
// check in base types first
18101826
if (baseTypes.find(scope) != baseTypes.end())
18111827
return true;
1828+
// check in base types base types
1829+
for (const std::string & base : baseTypes) {
1830+
const ScopeInfo3 * baseScope = findScope(base);
1831+
if (baseScope && baseScope->fullName == scope)
1832+
return true;
1833+
if (baseScope && baseScope->findTypeInBase(scope))
1834+
return true;
1835+
}
18121836
return false;
18131837
}
18141838
};

test/testsimplifyusing.cpp

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class TestSimplifyUsing : public TestFixture {
7979
TEST_CASE(simplifyUsing10008);
8080
TEST_CASE(simplifyUsing10054);
8181
TEST_CASE(simplifyUsing10136);
82+
TEST_CASE(simplifyUsing10171);
8283
}
8384

8485
std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Native, bool debugwarnings = true) {
@@ -984,7 +985,7 @@ class TestSimplifyUsing : public TestFixture {
984985
"namespace NS3 { "
985986
"class C : public A { "
986987
"public: "
987-
"void f ( const V & ) const override ; "
988+
"void f ( const std :: vector < char > & ) const override ; "
988989
"} ; "
989990
"void C :: f ( const V & ) const { } "
990991
"} "
@@ -998,9 +999,42 @@ class TestSimplifyUsing : public TestFixture {
998999
"c . f ( v ) ; "
9991000
"}";
10001001
TODO_ASSERT_EQUALS(exp, act, tok(code, true));
1001-
TODO_ASSERT_EQUALS("", "[test.cpp:20]: (debug) Executable scope 'f' with unknown function.\n", errout.str());
1002+
TODO_ASSERT_EQUALS("",
1003+
"[test.cpp:18]: (debug) Executable scope 'f' with unknown function.\n"
1004+
"[test.cpp:20]: (debug) Executable scope 'f' with unknown function.\n", errout.str());
10021005
}
10031006
}
1007+
1008+
void simplifyUsing10171() {
1009+
const char code[] = "namespace ns {\n"
1010+
" class A {\n"
1011+
" public:\n"
1012+
" using V = std::vector<unsigned char>;\n"
1013+
" virtual void f(const V&) const = 0;\n"
1014+
" };\n"
1015+
" class B : public A {\n"
1016+
" public:\n"
1017+
" void f(const V&) const override;\n"
1018+
" };\n"
1019+
"}\n"
1020+
"namespace ns {\n"
1021+
" void B::f(const std::vector<unsigned char>&) const { }\n"
1022+
"}";
1023+
const char exp[] = "namespace ns { "
1024+
"class A { "
1025+
"public: "
1026+
"virtual void f ( const std :: vector < unsigned char > & ) const = 0 ; "
1027+
"} ; "
1028+
"class B : public A { "
1029+
"public: "
1030+
"void f ( const std :: vector < unsigned char > & ) const override ; "
1031+
"} ; "
1032+
"} "
1033+
"namespace ns { "
1034+
"void B :: f ( const std :: vector < unsigned char > & ) const { } "
1035+
"}";
1036+
ASSERT_EQUALS(exp, tok(code, false));
1037+
}
10041038
};
10051039

10061040
REGISTER_TEST(TestSimplifyUsing)

0 commit comments

Comments
 (0)