fix some hangs in daca from uninstantiated template classes derived f… (#3133)

* fix some hangs in daca from uninstantiated template classes derived from itself

* remove assertions

* fix another simplifyUsing hang

Co-authored-by: Robert Reif <reif@FX6840>
This commit is contained in:
IOBYTE 2021-02-17 12:12:49 -05:00 committed by GitHub
parent 0619b873d0
commit 8547ff8cc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 17 deletions

View File

@ -3056,7 +3056,9 @@ const Token *Type::initBaseInfo(const Token *tok, const Token *tok1)
}
}
base.type = classScope->check->findType(base.nameTok, classScope);
const Type * baseType = classScope->check->findType(base.nameTok, enclosingScope);
if (baseType && !baseType->findDependency(this))
base.type = baseType;
// save pattern for base class name
derivedFrom.push_back(base);

View File

@ -1755,6 +1755,8 @@ namespace {
fullName = name;
ScopeInfo3 *scope = parent;
while (scope && scope->parent) {
if (scope->name.empty())
break;
fullName = scope->name + " :: " + fullName;
scope = scope->parent;
}
@ -1770,14 +1772,14 @@ namespace {
std::set<std::string> recordTypes;
std::set<std::string> baseTypes;
ScopeInfo3 *addChild(Type type, const std::string &name, const Token *bodyStart, const Token *bodyEnd) {
children.emplace_back(this, type, name, bodyStart, bodyEnd);
ScopeInfo3 *addChild(Type scopeType, const std::string &scopeName, const Token *bodyStartToken, const Token *bodyEndToken) {
children.emplace_back(this, scopeType, scopeName, bodyStartToken, bodyEndToken);
return &children.back();
}
bool hasChild(const std::string &name) const {
bool hasChild(const std::string &childName) const {
for (const auto & child : children) {
if (child.name == name)
if (child.name == childName)
return true;
}
return false;
@ -1824,24 +1826,39 @@ namespace {
return nullptr;
}
const ScopeInfo3 * findInChildren(const std::string & scope) const {
for (const auto & child : children) {
if (child.name == scope || child.fullName == scope)
return &child;
else {
const ScopeInfo3 * temp = child.findInChildren(scope);
if (temp)
return temp;
}
}
return nullptr;
}
const ScopeInfo3 * findScope(const std::string & scope) const {
const ScopeInfo3 * tempScope = this;
while (tempScope) {
// check children
for (const auto & child : tempScope->children) {
if (child.type == Record && (child.name == scope || child.fullName == scope))
if (&child != this && child.type == Record && (child.name == scope || child.fullName == scope))
return &child;
}
// check siblings for same name
if (tempScope->parent) {
for (const auto &sibling : tempScope->parent->children) {
if (sibling.name == tempScope->name && &sibling != this) {
const ScopeInfo3 * temp = sibling.findInChildren(scope);
if (temp)
return temp;
}
}
}
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;
}

View File

@ -5546,20 +5546,20 @@ private:
}
void const61() { // ticket #5606 - don't crash
// this code is invalid so a false negative is OK
checkConst("class MixerParticipant : public MixerParticipant {\n"
" int GetAudioFrame();\n"
"};\n"
"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 (but you may consider moving to unnamed namespace).\n", errout.str());
// this code is invalid so a false negative is OK
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 (but you may consider moving to unnamed namespace).\n", 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

View File

@ -65,6 +65,7 @@ private:
TEST_CASE(simplifyUsing16);
TEST_CASE(simplifyUsing17);
TEST_CASE(simplifyUsing18);
TEST_CASE(simplifyUsing19);
TEST_CASE(simplifyUsing8970);
TEST_CASE(simplifyUsing8971);
@ -463,6 +464,18 @@ private:
tok(code, false); // don't crash
}
void simplifyUsing19() {
const char code[] = "namespace a {\n"
"using b = int;\n"
"void foo::c() { }\n"
"void foo::d() { }\n"
"void foo::e() {\n"
" using b = float;\n"
"}\n"
"}";
tok(code, false); // don't hang
}
void simplifyUsing8970() {
const char code[] = "using V = std::vector<int>;\n"
"struct A {\n"