Fix #9467 (False positive on local variable when template specialization is used) (#2357)

This commit is contained in:
IOBYTE 2019-11-13 15:34:27 -05:00 committed by amai2012
parent da163ae0e8
commit f88ae21d8f
3 changed files with 54 additions and 1 deletions

View File

@ -2043,7 +2043,7 @@ void TemplateSimplifier::expandTemplate(
addNamespace(templateDeclaration, tok3);
}
mTokenList.addtoken(newName, tok3);
} else if (!Token::Match(tok3->next(), ":|{|="))
} else if (!Token::Match(tok3->next(), ":|{|=|;"))
tok3->str(newName);
continue;
}

View File

@ -189,6 +189,7 @@ private:
TEST_CASE(template149); // unknown macro
TEST_CASE(template150); // syntax error
TEST_CASE(template151); // crash
TEST_CASE(template152); // #9467
TEST_CASE(template_specialization_1); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
TEST_CASE(template_specialization_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
@ -3619,6 +3620,38 @@ private:
}
}
void template152() { // #9467
const char code[] = "class Foo {\n"
" template <unsigned int i>\n"
" bool bar() {\n"
" return true;\n"
" }\n"
"};\n"
"template <>\n"
"bool Foo::bar<9>() {\n"
" return true;\n"
"}\n"
"int global() {\n"
" int bar = 1;\n"
" return bar;\n"
"}";
const char exp[] = "class Foo { "
"bool bar<9> ( ) ; "
"template < unsigned int i > "
"bool bar ( ) { "
"return true ; "
"} "
"} ; "
"bool Foo :: bar<9> ( ) { "
"return true ; "
"} "
"int global ( ) { "
"int bar ; bar = 1 ; "
"return bar ; "
"}";
ASSERT_EQUALS(exp, tok(code));
}
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
const char code[] = "template <typename T> struct C {};\n"
"template <typename T> struct S {a};\n"

View File

@ -69,6 +69,7 @@ private:
TEST_CASE(uninitvar2_malloc); // malloc returns uninitialized data
TEST_CASE(uninitvar8); // ticket #6230
TEST_CASE(uninitvar9); // ticket #6424
TEST_CASE(uninitvar10); // ticket #9467
TEST_CASE(uninitvar_unconditionalTry);
TEST_CASE(uninitvar_funcptr); // #6404
TEST_CASE(uninitvar_operator); // #6680
@ -2664,6 +2665,25 @@ private:
"[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
}
void uninitvar10() { // 9467
const char code[] = "class Foo {\n"
" template <unsigned int i>\n"
" bool bar() {\n"
" return true;\n"
" }\n"
"};\n"
"template <>\n"
"bool Foo::bar<9>() {\n"
" return true;\n"
"}\n"
"int global() {\n"
" int bar = 1;\n"
" return bar;\n"
"}";
checkUninitVar(code, "test.cpp");
ASSERT_EQUALS("", errout.str());
}
void uninitvar_unconditionalTry() {
// Unconditional scopes and try{} scopes
checkUninitVar("int f() {\n"