diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 7f09400345c..41aa8456fc4 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -4388,13 +4388,13 @@ const Function * Function::getOverriddenFunctionRecursive(const ::Type* baseType auto range = parent->functionMap.equal_range(tokenDef->str()); for (std::multimap::const_iterator it = range.first; it != range.second; ++it) { const Function * func = it->second; - if (func->hasVirtualSpecifier()) { // Base is virtual and of same name + if (func->isImplicitlyVirtual()) { // Base is virtual and of same name const Token *temp1 = func->tokenDef->previous(); const Token *temp2 = tokenDef->previous(); bool match = true; // check for matching return parameters - while (temp1->str() != "virtual") { + while (!Token::Match(temp1, "virtual|public:|private:|protected:|{|}|;")) { if (temp1->str() != temp2->str() && !(temp1->str() == derivedFromType->name() && temp2->str() == baseType->name())) { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 149f5b3e36f..8c2bec6bd8f 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -249,6 +249,7 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(functionArgs20); TEST_CASE(functionImplicitlyVirtual); + TEST_CASE(functionGetOverridden); TEST_CASE(functionIsInlineKeyword); @@ -2730,6 +2731,24 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, function && function->isImplicitlyVirtual(false)); } + void functionGetOverridden() { + GET_SYMBOL_DB("struct B { virtual void f(); };\n" + "struct D : B {\n" + "public:\n" + " void f() override;\n" + "};\n" + "struct D2 : D { void f() override {} };\n"); + ASSERT(db != nullptr); + ASSERT_EQUALS(5, db->scopeList.size()); + const Function *func = db->scopeList.back().function; + ASSERT(func && func->nestedIn); + ASSERT_EQUALS("D2", func->nestedIn->className); + bool foundAllBaseClasses{}; + const Function* baseFunc = func->getOverriddenFunction(&foundAllBaseClasses); + ASSERT(baseFunc && baseFunc->nestedIn && foundAllBaseClasses); + ASSERT_EQUALS("D", baseFunc->nestedIn->className); + } + void functionIsInlineKeyword() { GET_SYMBOL_DB("inline void fs() {}"); (void)db;