From 90c464e1a4c06abd1c48720ca063b456cee10838 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:03:13 +0100 Subject: [PATCH] Fix #13593 Template not simplified with global scope operator (#7267) --- .selfcheck_suppressions | 4 +++- lib/templatesimplifier.cpp | 17 ++++++++++++++--- test/testsimplifytemplate.cpp | 17 +++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/.selfcheck_suppressions b/.selfcheck_suppressions index cec87cd9c47..ec4db9fa7e1 100644 --- a/.selfcheck_suppressions +++ b/.selfcheck_suppressions @@ -16,6 +16,8 @@ functionStatic:*/ui_fileview.h valueFlowBailout valueFlowBailoutIncompleteVar autoNoType +# ticket 11631 +templateInstantiation:test/testutils.cpp naming-varname:externals/simplecpp/simplecpp.h naming-privateMemberVariable:externals/simplecpp/simplecpp.h @@ -32,4 +34,4 @@ functionStatic:externals/tinyxml2/tinyxml2.h invalidPrintfArgType_uint:externals/tinyxml2/tinyxml2.cpp funcArgNamesDifferent:externals/tinyxml2/tinyxml2.cpp nullPointerRedundantCheck:externals/tinyxml2/tinyxml2.cpp -knownConditionTrueFalse:externals/tinyxml2/tinyxml2.cpp \ No newline at end of file +knownConditionTrueFalse:externals/tinyxml2/tinyxml2.cpp diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 59987a68b7c..c48217928ed 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -774,6 +774,19 @@ static bool areAllParamsTypes(const std::vector ¶ms) }); } +static bool isTemplateInstantion(const Token* tok) +{ + if (!tok->isName() || (tok->isKeyword() && !tok->isOperatorKeyword())) + return false; + if (Token::Match(tok->tokAt(-1), "%type% %name% ::|<")) + return true; + if (Token::Match(tok->tokAt(-2), "[,:] private|protected|public %name% ::|<")) + return true; + if (Token::Match(tok->tokAt(-1), "(|{|}|;|=|>|<<|:|.|*|&|return|<|,|!|[ %name% ::|<|(")) + return true; + return Token::Match(tok->tokAt(-2), "(|{|}|;|=|<<|:|.|*|&|return|<|,|!|[ :: %name% ::|<|("); +} + void TemplateSimplifier::getTemplateInstantiations() { std::multimap functionNameMap; @@ -830,9 +843,7 @@ void TemplateSimplifier::getTemplateInstantiations() Token *tok2 = Token::findsimplematch(tok->tokAt(2), ";"); if (tok2) tok = tok2; - } else if (Token::Match(tok->previous(), "(|{|}|;|=|>|<<|:|.|*|&|return|<|,|!|[ %name% ::|<|(") || - Token::Match(tok->previous(), "%type% %name% ::|<") || - Token::Match(tok->tokAt(-2), "[,:] private|protected|public %name% ::|<")) { + } else if (isTemplateInstantion(tok)) { if (!tok->scopeInfo()) syntaxError(tok); std::string scopeName = tok->scopeInfo()->name; diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index a25e11b9304..21be4f834e1 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -241,6 +241,7 @@ class TestSimplifyTemplate : public TestFixture { TEST_CASE(template_namespace_10); TEST_CASE(template_namespace_11); // #7145 TEST_CASE(template_namespace_12); + TEST_CASE(template_namespace_13); TEST_CASE(template_pointer_type); TEST_CASE(template_array_type); @@ -5313,6 +5314,22 @@ class TestSimplifyTemplate : public TestFixture { tok(code)); } + void template_namespace_13() { + const char code[] = "namespace N {\n" // #13593 + " template\n" + " struct S {\n" + " using U = T*;\n" + " };\n" + "}\n" + "::N::S::U u;\n"; + ASSERT_EQUALS("namespace N { " + "struct S ; " + "} " + "int * u ; " + "struct N :: S { } ;", + tok(code)); + } + void template_pointer_type() { const char code[] = "template void foo(const T x) {}\n" "void bar() { foo(0); }";