Skip to content

Commit 90c464e

Browse files
Fix #13593 Template not simplified with global scope operator (#7267)
1 parent 1ffb72f commit 90c464e

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

.selfcheck_suppressions

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ functionStatic:*/ui_fileview.h
1616
valueFlowBailout
1717
valueFlowBailoutIncompleteVar
1818
autoNoType
19+
# ticket 11631
20+
templateInstantiation:test/testutils.cpp
1921

2022
naming-varname:externals/simplecpp/simplecpp.h
2123
naming-privateMemberVariable:externals/simplecpp/simplecpp.h
@@ -32,4 +34,4 @@ functionStatic:externals/tinyxml2/tinyxml2.h
3234
invalidPrintfArgType_uint:externals/tinyxml2/tinyxml2.cpp
3335
funcArgNamesDifferent:externals/tinyxml2/tinyxml2.cpp
3436
nullPointerRedundantCheck:externals/tinyxml2/tinyxml2.cpp
35-
knownConditionTrueFalse:externals/tinyxml2/tinyxml2.cpp
37+
knownConditionTrueFalse:externals/tinyxml2/tinyxml2.cpp

lib/templatesimplifier.cpp

+14-3
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,19 @@ static bool areAllParamsTypes(const std::vector<const Token *> &params)
774774
});
775775
}
776776

777+
static bool isTemplateInstantion(const Token* tok)
778+
{
779+
if (!tok->isName() || (tok->isKeyword() && !tok->isOperatorKeyword()))
780+
return false;
781+
if (Token::Match(tok->tokAt(-1), "%type% %name% ::|<"))
782+
return true;
783+
if (Token::Match(tok->tokAt(-2), "[,:] private|protected|public %name% ::|<"))
784+
return true;
785+
if (Token::Match(tok->tokAt(-1), "(|{|}|;|=|>|<<|:|.|*|&|return|<|,|!|[ %name% ::|<|("))
786+
return true;
787+
return Token::Match(tok->tokAt(-2), "(|{|}|;|=|<<|:|.|*|&|return|<|,|!|[ :: %name% ::|<|(");
788+
}
789+
777790
void TemplateSimplifier::getTemplateInstantiations()
778791
{
779792
std::multimap<std::string, const TokenAndName *> functionNameMap;
@@ -830,9 +843,7 @@ void TemplateSimplifier::getTemplateInstantiations()
830843
Token *tok2 = Token::findsimplematch(tok->tokAt(2), ";");
831844
if (tok2)
832845
tok = tok2;
833-
} else if (Token::Match(tok->previous(), "(|{|}|;|=|>|<<|:|.|*|&|return|<|,|!|[ %name% ::|<|(") ||
834-
Token::Match(tok->previous(), "%type% %name% ::|<") ||
835-
Token::Match(tok->tokAt(-2), "[,:] private|protected|public %name% ::|<")) {
846+
} else if (isTemplateInstantion(tok)) {
836847
if (!tok->scopeInfo())
837848
syntaxError(tok);
838849
std::string scopeName = tok->scopeInfo()->name;

test/testsimplifytemplate.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ class TestSimplifyTemplate : public TestFixture {
241241
TEST_CASE(template_namespace_10);
242242
TEST_CASE(template_namespace_11); // #7145
243243
TEST_CASE(template_namespace_12);
244+
TEST_CASE(template_namespace_13);
244245
TEST_CASE(template_pointer_type);
245246
TEST_CASE(template_array_type);
246247

@@ -5313,6 +5314,22 @@ class TestSimplifyTemplate : public TestFixture {
53135314
tok(code));
53145315
}
53155316

5317+
void template_namespace_13() {
5318+
const char code[] = "namespace N {\n" // #13593
5319+
" template<typename T>\n"
5320+
" struct S {\n"
5321+
" using U = T*;\n"
5322+
" };\n"
5323+
"}\n"
5324+
"::N::S<int>::U u;\n";
5325+
ASSERT_EQUALS("namespace N { "
5326+
"struct S<int> ; "
5327+
"} "
5328+
"int * u ; "
5329+
"struct N :: S<int> { } ;",
5330+
tok(code));
5331+
}
5332+
53165333
void template_pointer_type() {
53175334
const char code[] = "template<class T> void foo(const T x) {}\n"
53185335
"void bar() { foo<int*>(0); }";

0 commit comments

Comments
 (0)