Skip to content

Commit 01097d7

Browse files
Fix #13444 FP uninitMemberVar caused by template specialization instantiated in wrong scope (#7124)
1 parent 625ea5e commit 01097d7

2 files changed

Lines changed: 29 additions & 0 deletions

File tree

lib/templatesimplifier.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,7 +2061,14 @@ void TemplateSimplifier::expandTemplate(
20612061
const std::string lastName = (templateInstantiation.name().find(' ') != std::string::npos) ? templateInstantiation.name().substr(templateInstantiation.name().rfind(' ')+1) : templateInstantiation.name();
20622062

20632063
std::stack<const Token *> templates;
2064+
int scopeCount = 0;
20642065
for (; tok3; tok3 = tok3->next()) {
2066+
if (tok3->str() == "{")
2067+
++scopeCount;
2068+
else if (tok3->str() == "}")
2069+
--scopeCount;
2070+
if (scopeCount < 0)
2071+
break;
20652072
if (tok3->isName() && !Token::Match(tok3, "class|typename|struct") && !tok3->isStandardType()) {
20662073
// search for this token in the type vector
20672074
unsigned int itype = 0;

test/testsimplifytemplate.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ class TestSimplifyTemplate : public TestFixture {
239239
TEST_CASE(template_namespace_9);
240240
TEST_CASE(template_namespace_10);
241241
TEST_CASE(template_namespace_11); // #7145
242+
TEST_CASE(template_namespace_12);
242243
TEST_CASE(template_pointer_type);
243244
TEST_CASE(template_array_type);
244245

@@ -5264,6 +5265,27 @@ class TestSimplifyTemplate : public TestFixture {
52645265
"} int MyNamespace :: TestClass :: TemplatedMethod<int> ( int t ) { return t ; }", tok(code));
52655266
}
52665267

5268+
void template_namespace_12() {
5269+
const char code[] = "struct S {};\n" // #13444
5270+
"namespace N {\n"
5271+
" template<>\n"
5272+
" struct hash<S> {};\n"
5273+
"}\n"
5274+
"struct T {\n"
5275+
" T(int i) : hash(i) {}\n"
5276+
" int hash;\n"
5277+
"};\n";
5278+
ASSERT_EQUALS("struct S { } ; "
5279+
"namespace N { "
5280+
"struct hash<S> { } ; "
5281+
"} "
5282+
"struct T { "
5283+
"T ( int i ) : hash ( i ) { } "
5284+
"int hash ; "
5285+
"} ;",
5286+
tok(code));
5287+
}
5288+
52675289
void template_pointer_type() {
52685290
const char code[] = "template<class T> void foo(const T x) {}\n"
52695291
"void bar() { foo<int*>(0); }";

0 commit comments

Comments
 (0)