diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 8b4a0fa1c..0beb610d1 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -626,13 +626,26 @@ void TemplateSimplifier::deleteToken(Token *tok) tok->deleteThis(); } -bool TemplateSimplifier::removeTemplate(Token *tok) +static void invalidateForwardDecls(const Token* beg, const Token* end, std::map* forwardDecls) { + if (!forwardDecls) + return; + for (auto& fwd : *forwardDecls) { + for (const Token* tok = beg; tok != end; tok = tok->next()) + if (fwd.second == tok) { + fwd.second = nullptr; + break; + } + } +} + +bool TemplateSimplifier::removeTemplate(Token *tok, std::map* forwardDecls) { if (!Token::simpleMatch(tok, "template <")) return false; Token *end = findTemplateDeclarationEnd(tok); if (end && end->next()) { + invalidateForwardDecls(tok, end->next(), forwardDecls); eraseTokens(tok, end->next()); deleteToken(tok); return true; @@ -2417,8 +2430,10 @@ static void invalidateInst(const Token* beg, const Token* end, std::vectornext()) - if (inst.token == tok) + if (inst.token == tok) { inst.token = nullptr; + break; + } } } @@ -3850,8 +3865,8 @@ void TemplateSimplifier::simplifyTemplates( // remove forward declaration if found auto it1 = mTemplateForwardDeclarationsMap.find(it->token()); if (it1 != mTemplateForwardDeclarationsMap.end()) - removeTemplate(it1->second); - removeTemplate(it->token()); + removeTemplate(it1->second, &mTemplateForwardDeclarationsMap); + removeTemplate(it->token(), &mTemplateForwardDeclarationsMap); } mTemplateDeclarations.erase(decl); } diff --git a/lib/templatesimplifier.h b/lib/templatesimplifier.h index a454b092e..b0e373bf3 100644 --- a/lib/templatesimplifier.h +++ b/lib/templatesimplifier.h @@ -457,7 +457,7 @@ private: /** * Remove a specific "template < ..." template class/function */ - static bool removeTemplate(Token *tok); + static bool removeTemplate(Token *tok, std::map* forwardDecls = nullptr); /** Syntax error */ NORETURN static void syntaxError(const Token *tok); diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index 4307e45c7..e3db648b0 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -4054,6 +4054,26 @@ private: "b> d100;"; // don't bother checking the output because this is not instantiated properly tok(code); // don't crash + + const char code2[] = "template void f();\n" // #11489 + "template void f(int);\n" + "void g() {\n" + " f();\n" + " f(1);\n" + "}\n" + "template\n" + "void f(int) {}\n" + "template\n" + "void f() {\n" + " f(0);\n" + "}\n"; + const char exp2[] = "template < typename T > void f ( ) ; " + "void f ( int ) ; " + "void f ( int ) ; " + "void g ( ) { f ( ) ; f ( 1 ) ; } " + "void f ( ) { f ( 0 ) ; } " + "void f ( int ) { }"; + ASSERT_EQUALS(exp2, tok(code2)); } void template159() { // #9886