Skip to content

Commit 8547ff8

Browse files
IOBYTERobert Reif
andauthored
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>
1 parent 0619b87 commit 8547ff8

4 files changed

Lines changed: 49 additions & 17 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3056,7 +3056,9 @@ const Token *Type::initBaseInfo(const Token *tok, const Token *tok1)
30563056
}
30573057
}
30583058

3059-
base.type = classScope->check->findType(base.nameTok, classScope);
3059+
const Type * baseType = classScope->check->findType(base.nameTok, enclosingScope);
3060+
if (baseType && !baseType->findDependency(this))
3061+
base.type = baseType;
30603062

30613063
// save pattern for base class name
30623064
derivedFrom.push_back(base);

lib/tokenize.cpp

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,6 +1755,8 @@ namespace {
17551755
fullName = name;
17561756
ScopeInfo3 *scope = parent;
17571757
while (scope && scope->parent) {
1758+
if (scope->name.empty())
1759+
break;
17581760
fullName = scope->name + " :: " + fullName;
17591761
scope = scope->parent;
17601762
}
@@ -1770,14 +1772,14 @@ namespace {
17701772
std::set<std::string> recordTypes;
17711773
std::set<std::string> baseTypes;
17721774

1773-
ScopeInfo3 *addChild(Type type, const std::string &name, const Token *bodyStart, const Token *bodyEnd) {
1774-
children.emplace_back(this, type, name, bodyStart, bodyEnd);
1775+
ScopeInfo3 *addChild(Type scopeType, const std::string &scopeName, const Token *bodyStartToken, const Token *bodyEndToken) {
1776+
children.emplace_back(this, scopeType, scopeName, bodyStartToken, bodyEndToken);
17751777
return &children.back();
17761778
}
17771779

1778-
bool hasChild(const std::string &name) const {
1780+
bool hasChild(const std::string &childName) const {
17791781
for (const auto & child : children) {
1780-
if (child.name == name)
1782+
if (child.name == childName)
17811783
return true;
17821784
}
17831785
return false;
@@ -1824,24 +1826,39 @@ namespace {
18241826
return nullptr;
18251827
}
18261828

1829+
const ScopeInfo3 * findInChildren(const std::string & scope) const {
1830+
for (const auto & child : children) {
1831+
if (child.name == scope || child.fullName == scope)
1832+
return &child;
1833+
else {
1834+
const ScopeInfo3 * temp = child.findInChildren(scope);
1835+
if (temp)
1836+
return temp;
1837+
}
1838+
}
1839+
return nullptr;
1840+
}
1841+
18271842
const ScopeInfo3 * findScope(const std::string & scope) const {
18281843
const ScopeInfo3 * tempScope = this;
18291844
while (tempScope) {
1845+
// check children
18301846
for (const auto & child : tempScope->children) {
1831-
if (child.type == Record && (child.name == scope || child.fullName == scope))
1847+
if (&child != this && child.type == Record && (child.name == scope || child.fullName == scope))
18321848
return &child;
18331849
}
1850+
// check siblings for same name
1851+
if (tempScope->parent) {
1852+
for (const auto &sibling : tempScope->parent->children) {
1853+
if (sibling.name == tempScope->name && &sibling != this) {
1854+
const ScopeInfo3 * temp = sibling.findInChildren(scope);
1855+
if (temp)
1856+
return temp;
1857+
}
1858+
}
1859+
}
18341860
tempScope = tempScope->parent;
18351861
}
1836-
// check for another scope with same name
1837-
const ScopeInfo3 * global = this;
1838-
while (global->parent)
1839-
global = global->parent;
1840-
for (const ScopeInfo3 & tempChild : global->children) {
1841-
const ScopeInfo3 * temp = tempChild.findScopeRecursive(scope);
1842-
if (temp)
1843-
return temp;
1844-
}
18451862
return nullptr;
18461863
}
18471864

test/testclass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5546,20 +5546,20 @@ class TestClass : public TestFixture {
55465546
}
55475547

55485548
void const61() { // ticket #5606 - don't crash
5549+
// this code is invalid so a false negative is OK
55495550
checkConst("class MixerParticipant : public MixerParticipant {\n"
55505551
" int GetAudioFrame();\n"
55515552
"};\n"
55525553
"int MixerParticipant::GetAudioFrame() {\n"
55535554
" return 0;\n"
55545555
"}");
5555-
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());
55565556

5557+
// this code is invalid so a false negative is OK
55575558
checkConst("class MixerParticipant : public MixerParticipant {\n"
55585559
" bool InitializeFileReader() {\n"
55595560
" printf(\"music\");\n"
55605561
" }\n"
55615562
"};");
5562-
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());
55635563

55645564
// Based on an example from SVN source code causing an endless recursion within CheckClass::isConstMemberFunc()
55655565
// A more complete example including a template declaration like

test/testsimplifyusing.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class TestSimplifyUsing : public TestFixture {
6565
TEST_CASE(simplifyUsing16);
6666
TEST_CASE(simplifyUsing17);
6767
TEST_CASE(simplifyUsing18);
68+
TEST_CASE(simplifyUsing19);
6869

6970
TEST_CASE(simplifyUsing8970);
7071
TEST_CASE(simplifyUsing8971);
@@ -463,6 +464,18 @@ class TestSimplifyUsing : public TestFixture {
463464
tok(code, false); // don't crash
464465
}
465466

467+
void simplifyUsing19() {
468+
const char code[] = "namespace a {\n"
469+
"using b = int;\n"
470+
"void foo::c() { }\n"
471+
"void foo::d() { }\n"
472+
"void foo::e() {\n"
473+
" using b = float;\n"
474+
"}\n"
475+
"}";
476+
tok(code, false); // don't hang
477+
}
478+
466479
void simplifyUsing8970() {
467480
const char code[] = "using V = std::vector<int>;\n"
468481
"struct A {\n"

0 commit comments

Comments
 (0)