Fixed #9070 (Segmentation fault in TemplateSimplifier::simplifyTemplateAliases (scram package)) (#1771)

This only fixes the crash.  It does not fix the underlying problem of
template using with templates of templates causing the use of deleted
instantiations.
This commit is contained in:
IOBYTE 2019-03-30 01:53:17 -04:00 committed by Daniel Marjamäki
parent d233b56d58
commit d88ee2d6a2
2 changed files with 22 additions and 2 deletions

View File

@ -1032,6 +1032,8 @@ void TemplateSimplifier::simplifyTemplateAliases()
TokenAndName &templateAlias = *it1;
++it1;
Token *startToken = templateAlias.token;
if (!startToken)
continue;
while (Token::Match(startToken->tokAt(-2), "%name% :: %name%"))
startToken = startToken->tokAt(-2);
if (!Token::Match(startToken->tokAt(-4), "> using %name% = %name% ::|<"))
@ -1061,15 +1063,17 @@ void TemplateSimplifier::simplifyTemplateAliases()
const Token *endToken = nullptr;
for (it2 = it1; it2 != mTemplateInstantiations.end(); ++it2) {
TokenAndName &aliasUsage = *it2;
if (aliasUsage.name != aliasName)
if (!aliasUsage.token || aliasUsage.name != aliasName)
continue;
std::vector<std::pair<Token *, Token *>> args;
Token *tok2 = aliasUsage.token->tokAt(2);
while (tok2) {
Token * const start = tok2;
while (tok2 && !Token::Match(tok2, "[,>;{}]")) {
if (tok2->link() && Token::Match(tok2, "(|<|["))
if (tok2->link() && Token::Match(tok2, "(|["))
tok2 = tok2->link();
else if (tok2->str() == "<")
tok2 = tok2->findClosingBracket();
tok2 = tok2->next();
}

View File

@ -178,6 +178,7 @@ private:
TEST_CASE(templateAlias1);
TEST_CASE(templateAlias2);
TEST_CASE(templateAlias3); // #8315
TEST_CASE(templateAlias4); // #9070
// Test TemplateSimplifier::instantiateMatch
TEST_CASE(instantiateMatch);
@ -3321,6 +3322,21 @@ private:
ASSERT_EQUALS(expected, tok(code));
}
void templateAlias4() { // #9070
const char code[] = "template <class T>\n"
"using IntrusivePtr = boost::intrusive_ptr<T>;\n"
"template <class T> class Vertex { };\n"
"IntrusivePtr<Vertex<int>> p;";
const char expected[] = "; "
"class Vertex<int> ; "
"boost :: intrusive_ptr < Vertex<int> > p ;"
"class Vertex<int> { } ;";
const char actual[] = "; "
"template < class T > class Vertex { } ; "
"boost :: intrusive_ptr < T > p ;";
TODO_ASSERT_EQUALS(expected, actual, tok(code));
}
unsigned int instantiateMatch(const char code[], const std::size_t numberOfArguments, const char patternAfter[]) {
Tokenizer tokenizer(&settings, this);