From 8b6cbe2e9ede9c7dc975e119a17ba5d989749daf Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:57:38 +0100 Subject: [PATCH] Fix crash in SymbolDatabase::addClassFunction() (f'up to #12209) (#5689) --- lib/symboldatabase.cpp | 2 +- test/testsymboldatabase.cpp | 62 ++++++++++++++++++++++++------------- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index dd8c6d0bf..d7612bbea 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -3286,7 +3286,7 @@ void SymbolDatabase::addClassFunction(Scope **scope, const Token **tok, const To tok1 = tok1->tokAt(2); scope2 = scope2->findRecordInNestedList(tok1->str()); } - if (isAnonymousNamespace) + if (scope2 && isAnonymousNamespace) scope2 = scope2->findRecordInNestedList(tok1->str()); if (count == 1 && scope2) { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 559adb261..ff6a6b6e6 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -5464,27 +5464,47 @@ private: void createSymbolDatabaseFindAllScopes7() { - GET_SYMBOL_DB("namespace {\n" - " struct S {\n" - " void f();\n" - " };\n" - "}\n" - "void S::f() {}\n"); - ASSERT(db); - ASSERT_EQUALS(4, db->scopeList.size()); - auto anon = db->scopeList.begin(); - ++anon; - ASSERT(anon->className.empty()); - ASSERT_EQUALS(anon->type, Scope::eNamespace); - auto S = anon; - ++S; - ASSERT_EQUALS(S->type, Scope::eStruct); - ASSERT_EQUALS(S->className, "S"); - ASSERT_EQUALS(S->nestedIn, &*anon); - const Token* f = Token::findsimplematch(tokenizer.tokens(), "f ( ) {"); - ASSERT(f && f->function() && f->function()->functionScope && f->function()->functionScope->bodyStart); - ASSERT_EQUALS(f->function()->functionScope->functionOf, &*S); - ASSERT_EQUALS(f->function()->functionScope->bodyStart->linenr(), 6); + { + GET_SYMBOL_DB("namespace {\n" + " struct S {\n" + " void f();\n" + " };\n" + "}\n" + "void S::f() {}\n"); + ASSERT(db); + ASSERT_EQUALS(4, db->scopeList.size()); + auto anon = db->scopeList.begin(); + ++anon; + ASSERT(anon->className.empty()); + ASSERT_EQUALS(anon->type, Scope::eNamespace); + auto S = anon; + ++S; + ASSERT_EQUALS(S->type, Scope::eStruct); + ASSERT_EQUALS(S->className, "S"); + ASSERT_EQUALS(S->nestedIn, &*anon); + const Token* f = Token::findsimplematch(tokenizer.tokens(), "f ( ) {"); + ASSERT(f && f->function() && f->function()->functionScope && f->function()->functionScope->bodyStart); + ASSERT_EQUALS(f->function()->functionScope->functionOf, &*S); + ASSERT_EQUALS(f->function()->functionScope->bodyStart->linenr(), 6); + } + { + GET_SYMBOL_DB("namespace {\n" + " int i = 0;\n" + "}\n" + "namespace N {\n" + " namespace {\n" + " template\n" + " struct S {\n" + " void f();\n" + " };\n" + " template\n" + " void S::f() {}\n" + " }\n" + " S g() { return {}; }\n" + "}\n"); + ASSERT(db); // don't crash + ASSERT_EQUALS("", errout.str()); + } } void createSymbolDatabaseIncompleteVars()