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:
parent
0619b873d0
commit
8547ff8cc2
|
@ -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
|
// save pattern for base class name
|
||||||
derivedFrom.push_back(base);
|
derivedFrom.push_back(base);
|
||||||
|
|
|
@ -1755,6 +1755,8 @@ namespace {
|
||||||
fullName = name;
|
fullName = name;
|
||||||
ScopeInfo3 *scope = parent;
|
ScopeInfo3 *scope = parent;
|
||||||
while (scope && scope->parent) {
|
while (scope && scope->parent) {
|
||||||
|
if (scope->name.empty())
|
||||||
|
break;
|
||||||
fullName = scope->name + " :: " + fullName;
|
fullName = scope->name + " :: " + fullName;
|
||||||
scope = scope->parent;
|
scope = scope->parent;
|
||||||
}
|
}
|
||||||
|
@ -1770,14 +1772,14 @@ namespace {
|
||||||
std::set<std::string> recordTypes;
|
std::set<std::string> recordTypes;
|
||||||
std::set<std::string> baseTypes;
|
std::set<std::string> baseTypes;
|
||||||
|
|
||||||
ScopeInfo3 *addChild(Type type, const std::string &name, const Token *bodyStart, const Token *bodyEnd) {
|
ScopeInfo3 *addChild(Type scopeType, const std::string &scopeName, const Token *bodyStartToken, const Token *bodyEndToken) {
|
||||||
children.emplace_back(this, type, name, bodyStart, bodyEnd);
|
children.emplace_back(this, scopeType, scopeName, bodyStartToken, bodyEndToken);
|
||||||
return &children.back();
|
return &children.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasChild(const std::string &name) const {
|
bool hasChild(const std::string &childName) const {
|
||||||
for (const auto & child : children) {
|
for (const auto & child : children) {
|
||||||
if (child.name == name)
|
if (child.name == childName)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -1824,24 +1826,39 @@ namespace {
|
||||||
return nullptr;
|
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 * findScope(const std::string & scope) const {
|
||||||
const ScopeInfo3 * tempScope = this;
|
const ScopeInfo3 * tempScope = this;
|
||||||
while (tempScope) {
|
while (tempScope) {
|
||||||
|
// check children
|
||||||
for (const auto & child : tempScope->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;
|
return &child;
|
||||||
}
|
}
|
||||||
tempScope = tempScope->parent;
|
// check siblings for same name
|
||||||
}
|
if (tempScope->parent) {
|
||||||
// check for another scope with same name
|
for (const auto &sibling : tempScope->parent->children) {
|
||||||
const ScopeInfo3 * global = this;
|
if (sibling.name == tempScope->name && &sibling != this) {
|
||||||
while (global->parent)
|
const ScopeInfo3 * temp = sibling.findInChildren(scope);
|
||||||
global = global->parent;
|
|
||||||
for (const ScopeInfo3 & tempChild : global->children) {
|
|
||||||
const ScopeInfo3 * temp = tempChild.findScopeRecursive(scope);
|
|
||||||
if (temp)
|
if (temp)
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tempScope = tempScope->parent;
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5546,20 +5546,20 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void const61() { // ticket #5606 - don't crash
|
void const61() { // ticket #5606 - don't crash
|
||||||
|
// this code is invalid so a false negative is OK
|
||||||
checkConst("class MixerParticipant : public MixerParticipant {\n"
|
checkConst("class MixerParticipant : public MixerParticipant {\n"
|
||||||
" int GetAudioFrame();\n"
|
" int GetAudioFrame();\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"int MixerParticipant::GetAudioFrame() {\n"
|
"int MixerParticipant::GetAudioFrame() {\n"
|
||||||
" return 0;\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"
|
checkConst("class MixerParticipant : public MixerParticipant {\n"
|
||||||
" bool InitializeFileReader() {\n"
|
" bool InitializeFileReader() {\n"
|
||||||
" printf(\"music\");\n"
|
" printf(\"music\");\n"
|
||||||
" }\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()
|
// Based on an example from SVN source code causing an endless recursion within CheckClass::isConstMemberFunc()
|
||||||
// A more complete example including a template declaration like
|
// A more complete example including a template declaration like
|
||||||
|
|
|
@ -65,6 +65,7 @@ private:
|
||||||
TEST_CASE(simplifyUsing16);
|
TEST_CASE(simplifyUsing16);
|
||||||
TEST_CASE(simplifyUsing17);
|
TEST_CASE(simplifyUsing17);
|
||||||
TEST_CASE(simplifyUsing18);
|
TEST_CASE(simplifyUsing18);
|
||||||
|
TEST_CASE(simplifyUsing19);
|
||||||
|
|
||||||
TEST_CASE(simplifyUsing8970);
|
TEST_CASE(simplifyUsing8970);
|
||||||
TEST_CASE(simplifyUsing8971);
|
TEST_CASE(simplifyUsing8971);
|
||||||
|
@ -463,6 +464,18 @@ private:
|
||||||
tok(code, false); // don't crash
|
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() {
|
void simplifyUsing8970() {
|
||||||
const char code[] = "using V = std::vector<int>;\n"
|
const char code[] = "using V = std::vector<int>;\n"
|
||||||
"struct A {\n"
|
"struct A {\n"
|
||||||
|
|
Loading…
Reference in New Issue