From f88ae21d8fda0c896ac533af9a68071966cbe579 Mon Sep 17 00:00:00 2001 From: IOBYTE Date: Wed, 13 Nov 2019 15:34:27 -0500 Subject: [PATCH] Fix #9467 (False positive on local variable when template specialization is used) (#2357) --- lib/templatesimplifier.cpp | 2 +- test/testsimplifytemplate.cpp | 33 +++++++++++++++++++++++++++++++++ test/testuninitvar.cpp | 20 ++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index e7a3341d0..70dedeb0a 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -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; } diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index 7b0dbbbb2..fb2b6d5d4 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -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 struct S> {..}; TEST_CASE(template_specialization_2); // #7868 - template specialization template struct S> {..}; 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 \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 struct S> {..}; const char code[] = "template struct C {};\n" "template struct S {a};\n" diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 8f6ed3a67..0f028512e 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -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 \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"