Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/symboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
45 changes: 31 additions & 14 deletions lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
4 changes: 2 additions & 2 deletions test/testclass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5546,20 +5546,20 @@ class TestClass : public TestFixture {
}

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
Expand Down
13 changes: 13 additions & 0 deletions test/testsimplifyusing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class TestSimplifyUsing : public TestFixture {
TEST_CASE(simplifyUsing16);
TEST_CASE(simplifyUsing17);
TEST_CASE(simplifyUsing18);
TEST_CASE(simplifyUsing19);

TEST_CASE(simplifyUsing8970);
TEST_CASE(simplifyUsing8971);
Expand Down Expand Up @@ -463,6 +464,18 @@ class TestSimplifyUsing : public TestFixture {
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"
Expand Down