* Add test for #11489 * Fix #11489 Crash in TemplateSimplifier
This commit is contained in:
parent
043f4fa621
commit
51cba8162b
|
@ -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<Token*, Token*>* 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<Token*, Token*>* 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::vector<newIn
|
|||
return;
|
||||
for (auto& inst : *newInst) {
|
||||
for (const Token* tok = beg; tok != end; tok = tok->next())
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -457,7 +457,7 @@ private:
|
|||
/**
|
||||
* Remove a specific "template < ..." template class/function
|
||||
*/
|
||||
static bool removeTemplate(Token *tok);
|
||||
static bool removeTemplate(Token *tok, std::map<Token*, Token*>* forwardDecls = nullptr);
|
||||
|
||||
/** Syntax error */
|
||||
NORETURN static void syntaxError(const Token *tok);
|
||||
|
|
|
@ -4054,6 +4054,26 @@ private:
|
|||
"b<a100<int>> d100;";
|
||||
// don't bother checking the output because this is not instantiated properly
|
||||
tok(code); // don't crash
|
||||
|
||||
const char code2[] = "template<typename T> void f();\n" // #11489
|
||||
"template<typename T> void f(int);\n"
|
||||
"void g() {\n"
|
||||
" f<int>();\n"
|
||||
" f<char>(1);\n"
|
||||
"}\n"
|
||||
"template<typename T>\n"
|
||||
"void f(int) {}\n"
|
||||
"template<typename T>\n"
|
||||
"void f() {\n"
|
||||
" f<T>(0);\n"
|
||||
"}\n";
|
||||
const char exp2[] = "template < typename T > void f ( ) ; "
|
||||
"void f<int> ( int ) ; "
|
||||
"void f<char> ( int ) ; "
|
||||
"void g ( ) { f<int> ( ) ; f<char> ( 1 ) ; } "
|
||||
"void f<int> ( ) { f<int> ( 0 ) ; } "
|
||||
"void f<char> ( int ) { }";
|
||||
ASSERT_EQUALS(exp2, tok(code2));
|
||||
}
|
||||
|
||||
void template159() { // #9886
|
||||
|
|
Loading…
Reference in New Issue