Skip to content

Commit

Permalink
Fix #12958 reopened Stack overflow with using namespace (#6639)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github committed Jul 24, 2024
1 parent d37f463 commit fc6de74
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 5 deletions.
13 changes: 8 additions & 5 deletions lib/symboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6123,7 +6123,7 @@ const Scope *SymbolDatabase::findScopeByName(const std::string& name) const
//---------------------------------------------------------------------------

template<class S, class T, REQUIRES("S must be a Scope class", std::is_convertible<S*, const Scope*> ), REQUIRES("T must be a Type class", std::is_convertible<T*, const Type*> )>
S* findRecordInNestedListImpl(S& thisScope, const std::string & name, bool isC)
S* findRecordInNestedListImpl(S& thisScope, const std::string& name, bool isC, std::set<const Scope*>& visited)
{
for (S* scope: thisScope.nestedList) {
if (scope->className == name && scope->type != Scope::eFunction)
Expand All @@ -6136,9 +6136,10 @@ S* findRecordInNestedListImpl(S& thisScope, const std::string & name, bool isC)
}

for (const auto& u : thisScope.usingList) {
if (!u.scope || u.scope == &thisScope)
if (!u.scope || u.scope == &thisScope || visited.find(u.scope) != visited.end())
continue;
S* nestedScope = const_cast<S*>(u.scope)->findRecordInNestedList(name, false);
visited.emplace(u.scope);
S* nestedScope = findRecordInNestedListImpl<S, T>(const_cast<S&>(*u.scope), name, false, visited);
if (nestedScope)
return nestedScope;
}
Expand All @@ -6158,12 +6159,14 @@ S* findRecordInNestedListImpl(S& thisScope, const std::string & name, bool isC)

const Scope* Scope::findRecordInNestedList(const std::string & name, bool isC) const
{
return findRecordInNestedListImpl<const Scope, const Type>(*this, name, isC);
std::set<const Scope*> visited;
return findRecordInNestedListImpl<const Scope, const Type>(*this, name, isC, visited);
}

Scope* Scope::findRecordInNestedList(const std::string & name, bool isC)
{
return findRecordInNestedListImpl<Scope, Type>(*this, name, isC);
std::set<const Scope*> visited;
return findRecordInNestedListImpl<Scope, Type>(*this, name, isC, visited);
}

//---------------------------------------------------------------------------
Expand Down
14 changes: 14 additions & 0 deletions test/testsymboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5609,6 +5609,20 @@ class TestSymbolDatabase : public TestFixture {
ASSERT(db != nullptr);
ASSERT_EQUALS("", errout_str());
}
{
GET_SYMBOL_DB_DBG("namespace N {\n"
" struct S {};\n"
"}\n"
"namespace O {\n"
" using namespace N;\n"
"}\n"
"namespace N {\n"
" using namespace O;\n"
" struct T {};\n"
"}\n");
ASSERT(db != nullptr);
ASSERT_EQUALS("", errout_str());
}
}

void createSymbolDatabaseFindAllScopes1() {
Expand Down

0 comments on commit fc6de74

Please sign in to comment.