Fixed #7697 ((debug) Executable scope 'B' with unknown function.)

This commit is contained in:
Robert Reif 2016-08-19 19:06:15 +02:00 committed by Daniel Marjamäki
parent 789aef7fde
commit 1e999e0cfe
3 changed files with 56 additions and 3 deletions

View File

@ -1791,10 +1791,12 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se
}
}
// nested class variable
// nested or base class variable
else if (depth == 0 && Token::Match(first->next(), "%name%") &&
second->next()->str() == scope->className && second->strAt(2) == "::" &&
first->next()->str() == second->strAt(3)) {
Token::Match(second->next(), "%name% :: %name%") &&
((second->next()->str() == scope->className) ||
(scope->definedType && scope->definedType->isDerivedFrom(second->next()->str()))) &&
(first->next()->str() == second->strAt(3))) {
second = second->tokAt(2);
}
@ -2249,6 +2251,17 @@ bool Type::findDependency(const Type* ancestor) const
return false;
}
bool Type::isDerivedFrom(const std::string & ancestor) const
{
for (std::vector<BaseInfo>::const_iterator parent=derivedFrom.begin(); parent!=derivedFrom.end(); ++parent) {
if (parent->name == ancestor)
return true;
if (parent->type && parent->type->isDerivedFrom(ancestor))
return true;
}
return false;
}
bool Variable::arrayDimensions(const Library* lib)
{
const Library::Container* container = lib->detectContainer(_start);

View File

@ -142,6 +142,8 @@ public:
* @return true if there is a dependency
*/
bool findDependency(const Type* ancestor) const;
bool isDerivedFrom(const std::string & ancestor) const;
};
class CPPCHECKLIB Enumerator {

View File

@ -190,6 +190,7 @@ private:
TEST_CASE(functionArgs10);
TEST_CASE(functionArgs11);
TEST_CASE(functionArgs12); // #7661
TEST_CASE(functionArgs13); // #7697
TEST_CASE(namespaces1);
TEST_CASE(namespaces2);
@ -1830,6 +1831,43 @@ private:
}
}
void functionArgs13() { // #7697
GET_SYMBOL_DB("struct A {\n"
" enum E { };\n"
" struct S { };\n"
"};\n"
"struct B : public A {\n"
" B(E e);\n"
" B(S s);\n"
"};\n"
"B::B(A::E e) { }\n"
"B::B(A::S s) { }");
ASSERT_EQUALS(true, db != nullptr);
if (db) {
const Token *f = Token::findsimplematch(tokenizer.tokens(), "B ( A :: E");
ASSERT_EQUALS(true, f && f->function());
if (f && f->function()) {
const Function *func = f->function();
ASSERT_EQUALS(true, func->argumentList.size() == 1 && func->argumentList.front().type());
if (func->argumentList.size() == 1 && func->argumentList.front().type()) {
const Type * type = func->argumentList.front().type();
ASSERT_EQUALS(true, type->isEnumType() && type->name() == "E");
}
}
f = Token::findsimplematch(tokenizer.tokens(), "B ( A :: S");
ASSERT_EQUALS(true, f && f->function());
if (f && f->function()) {
const Function *func = f->function();
ASSERT_EQUALS(true, func->argumentList.size() == 1 && func->argumentList.front().type());
if (func->argumentList.size() == 1 && func->argumentList.front().type()) {
const Type * type = func->argumentList.front().type();
ASSERT_EQUALS(true, type->isStructType() && type->name() == "S");
}
}
}
}
void namespaces1() {
GET_SYMBOL_DB("namespace fred {\n"
" namespace barney {\n"