Skip to content

Commit

Permalink
Fix #13593 Template not simplified with global scope operator (#7267)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github authored Jan 28, 2025
1 parent 1ffb72f commit 90c464e
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
4 changes: 3 additions & 1 deletion .selfcheck_suppressions
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
knownConditionTrueFalse:externals/tinyxml2/tinyxml2.cpp
17 changes: 14 additions & 3 deletions lib/templatesimplifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,19 @@ static bool areAllParamsTypes(const std::vector<const Token *> &params)
});
}

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<std::string, const TokenAndName *> functionNameMap;
Expand Down Expand Up @@ -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;
Expand Down
17 changes: 17 additions & 0 deletions test/testsimplifytemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -5313,6 +5314,22 @@ class TestSimplifyTemplate : public TestFixture {
tok(code));
}

void template_namespace_13() {
const char code[] = "namespace N {\n" // #13593
" template<typename T>\n"
" struct S {\n"
" using U = T*;\n"
" };\n"
"}\n"
"::N::S<int>::U u;\n";
ASSERT_EQUALS("namespace N { "
"struct S<int> ; "
"} "
"int * u ; "
"struct N :: S<int> { } ;",
tok(code));
}

void template_pointer_type() {
const char code[] = "template<class T> void foo(const T x) {}\n"
"void bar() { foo<int*>(0); }";
Expand Down

0 comments on commit 90c464e

Please sign in to comment.