From fc6de74ea7a3dc2a6f5315c49e01f7930bf0b879 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:58:44 +0200 Subject: [PATCH] Fix #12958 reopened Stack overflow with using namespace (#6639) --- lib/symboldatabase.cpp | 13 ++++++++----- test/testsymboldatabase.cpp | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 4082a894e2f..9bdff3f622c 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -6123,7 +6123,7 @@ const Scope *SymbolDatabase::findScopeByName(const std::string& name) const //--------------------------------------------------------------------------- template ), REQUIRES("T must be a Type class", std::is_convertible )> -S* findRecordInNestedListImpl(S& thisScope, const std::string & name, bool isC) +S* findRecordInNestedListImpl(S& thisScope, const std::string& name, bool isC, std::set& visited) { for (S* scope: thisScope.nestedList) { if (scope->className == name && scope->type != Scope::eFunction) @@ -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(u.scope)->findRecordInNestedList(name, false); + visited.emplace(u.scope); + S* nestedScope = findRecordInNestedListImpl(const_cast(*u.scope), name, false, visited); if (nestedScope) return nestedScope; } @@ -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(*this, name, isC); + std::set visited; + return findRecordInNestedListImpl(*this, name, isC, visited); } Scope* Scope::findRecordInNestedList(const std::string & name, bool isC) { - return findRecordInNestedListImpl(*this, name, isC); + std::set visited; + return findRecordInNestedListImpl(*this, name, isC, visited); } //--------------------------------------------------------------------------- diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index baa847d5dd9..5a69a402fbe 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -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() {