diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 824c35ba7..d75fc2938 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2834,6 +2834,10 @@ static void removeTemplates(Token *tok) tok->deleteThis(); goback = true; break; + } else if (tok2->str() == "}") { // garbage code! (#3449) + Token::eraseTokens(tok,tok2); + tok->deleteThis(); + break; } // don't remove constructor if (tok2->str() == "explicit") { diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index c128e0ca7..1b6de6f1a 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -119,6 +119,7 @@ private: TEST_CASE(template26); // #2721 - passing 'char[2]' as template parameter TEST_CASE(template27); // #3350 - removing unused template in macro call TEST_CASE(template28); + TEST_CASE(template29); // #3449 TEST_CASE(template_unhandled); TEST_CASE(template_default_parameter); TEST_CASE(template_default_type); @@ -2086,6 +2087,14 @@ private: ASSERT_EQUALS("Fred> x ; class Fred { } class Fred> { }", sizeof_(code)); } + void template29() { + // #3449 - garbage code (don't segfault) + const char code[] = "template struct A;\n" + "struct B { template struct C };\n" + "{};"; + ASSERT_EQUALS("struct B { } ; { } ;", sizeof_(code)); + } + void template_unhandled() { // An unhandled template usage should be simplified.. ASSERT_EQUALS("x ( ) ;", sizeof_("x();"));