#6298 stack overflow in Scope::findFunctionInBase (endless recursion). Fix handling of circular class hierarchy
This commit is contained in:
parent
108b035af2
commit
480a5672b0
|
@ -844,8 +844,16 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
|||
// fill in base class info
|
||||
for (std::list<Type>::iterator it = typeList.begin(); it != typeList.end(); ++it) {
|
||||
// finish filling in base class info
|
||||
for (unsigned int i = 0; i < it->derivedFrom.size(); ++i)
|
||||
it->derivedFrom[i].type = findType(it->derivedFrom[i].nameTok, it->enclosingScope);
|
||||
for (unsigned int i = 0; i < it->derivedFrom.size(); ++i) {
|
||||
const Type* found = findType(it->derivedFrom[i].nameTok, it->enclosingScope);
|
||||
if (found && found->findDependency(&(*it))) {
|
||||
// circular dependency
|
||||
//_tokenizer->syntaxError(nullptr);
|
||||
}
|
||||
else {
|
||||
it->derivedFrom[i].type = found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fill in friend info
|
||||
|
@ -2054,6 +2062,16 @@ bool Type::hasCircularDependencies(std::set<BaseInfo>* anchestors) const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Type::findDependency(const Type* anchestor) const {
|
||||
if (this==anchestor)
|
||||
return true;
|
||||
for (std::vector<BaseInfo>::const_iterator parent=derivedFrom.begin(); parent!=derivedFrom.end(); ++parent) {
|
||||
if (parent->type && parent->type->findDependency(anchestor))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Variable::arrayDimensions(const Library* lib)
|
||||
{
|
||||
const Library::Container* container = lib->detectContainer(_start);
|
||||
|
|
|
@ -122,7 +122,14 @@ public:
|
|||
* @param anchestors list of anchestors. For internal usage only, clients should not supply this argument.
|
||||
* @return true if there is a circular dependency
|
||||
*/
|
||||
bool hasCircularDependencies(std::set<BaseInfo>* anchestors = 0) const;
|
||||
bool hasCircularDependencies(std::set<BaseInfo>* anchestors = nullptr) const;
|
||||
|
||||
/**
|
||||
* Check for dependency
|
||||
* @param anchestor potential anchestor
|
||||
* @return true if there is a dependency
|
||||
*/
|
||||
bool findDependency(const Type* anchestor) const;
|
||||
};
|
||||
|
||||
/** @brief Information about a member variable. */
|
||||
|
|
|
@ -4929,14 +4929,14 @@ private:
|
|||
"int MixerParticipant::GetAudioFrame() {\n"
|
||||
" return 0;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:2]: (performance, inconclusive) Technically the member function 'MixerParticipant::GetAudioFrame' can be static.\n", errout.str());
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
checkConst("class MixerParticipant : public MixerParticipant {\n"
|
||||
" bool InitializeFileReader() {\n"
|
||||
" printf(\"music\");\n"
|
||||
" }\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (performance, inconclusive) Technically the member function 'MixerParticipant::InitializeFileReader' can be static.\n", errout.str());
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// Based on an example from SVN source code causing an endless recursion within CheckClass::isConstMemberFunc()
|
||||
// A more complete example including a template declaration like
|
||||
|
|
|
@ -260,6 +260,7 @@ private:
|
|||
TEST_CASE(functionPrototype); // ticket #5867
|
||||
|
||||
TEST_CASE(lambda); // ticket #5867
|
||||
TEST_CASE(circularDependencies); // 6298
|
||||
}
|
||||
|
||||
void array() const {
|
||||
|
@ -2914,6 +2915,21 @@ private:
|
|||
ASSERT_EQUALS(Scope::eLambda, scope->type);
|
||||
}
|
||||
}
|
||||
// #6298 "stack overflow in Scope::findFunctionInBase (endless recursion)"
|
||||
void circularDependencies() {
|
||||
check("template<template<class> class E,class D> class C : E<D> {\n"
|
||||
" public:\n"
|
||||
" int f();\n"
|
||||
"};\n"
|
||||
"class E : C<D,int> {\n"
|
||||
" public:\n"
|
||||
" int f() { return C< ::D,int>::f(); }\n"
|
||||
"};\n"
|
||||
"int main() {\n"
|
||||
" E c;\n"
|
||||
" c.f();\n"
|
||||
"}");
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestSymbolDatabase)
|
||||
|
|
|
@ -722,7 +722,7 @@ private:
|
|||
" C a;\n"
|
||||
"}");
|
||||
|
||||
ASSERT_EQUALS("[test.cpp:10]: (style) Unused private function: 'InfiniteA::foo'\n", errout.str());
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void staticVariable() {
|
||||
|
|
Loading…
Reference in New Issue