From 389e446dc05297e72d4f2023ef3625a84b95aa9c Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Wed, 2 Aug 2023 04:29:19 -0400 Subject: [PATCH] Fix 11848: Assert failure in getParentValueTypes() (#5274) --- lib/symboldatabase.cpp | 28 ++++++++++++++++++++-------- lib/symboldatabase.h | 2 +- test/testvalueflow.cpp | 8 ++++++++ 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 14e7ece42..99e3f4815 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -3490,16 +3490,28 @@ const Token *Type::initBaseInfo(const Token *tok, const Token *tok1) return tok2; } -const std::string& Type::name() const +std::string Type::name() const { - const Token* next = classDef->next(); + const Token* start = classDef->next(); if (classScope && classScope->enumClass && isEnumType()) - return next->strAt(1); - if (next->str() == "class") - return next->strAt(1); - if (next->isName()) - return next->str(); - return emptyString; + start = start->tokAt(1); + else if (start->str() == "class") + start = start->tokAt(1); + else if (!start->isName()) + return emptyString; + const Token* next = start; + while (Token::Match(next, "::|<|>|(|)|[|]|*|&|&&|%name%")) { + if (Token::Match(next, "<|(|[") && next->link()) + next = next->link(); + next = next->next(); + } + std::string result; + for (const Token* tok = start; tok != next; tok = tok->next()) { + if (!result.empty()) + result += ' '; + result += tok->str(); + } + return result; } void SymbolDatabase::debugMessage(const Token *tok, const std::string &type, const std::string &msg) const diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index ffd321763..aa7d644a6 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -131,7 +131,7 @@ public: } } - const std::string& name() const; + std::string name() const; const std::string& type() const { return classDef ? classDef->str() : emptyString; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 2592eeec6..4e3225961 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -6812,6 +6812,14 @@ private: " dummy_resource::log.clear();\n" "}\n"; valueOfTok(code, "log"); + + code = "struct D : B {\n" + " D(int i, const std::string& s) : B(i, s) {}\n" + "};\n" + "template<> struct B::S {\n" + " int j;\n" + "};\n"; + valueOfTok(code, "B"); } void valueFlowCrash() {