From d88ee2d6a21e07f0b974f8cfd2d577c239393fa1 Mon Sep 17 00:00:00 2001 From: IOBYTE Date: Sat, 30 Mar 2019 01:53:17 -0400 Subject: [PATCH] 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. --- lib/templatesimplifier.cpp | 8 ++++++-- test/testsimplifytemplate.cpp | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 1d956a3e9..3acaf392f 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -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> 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(); } diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index ad02bf6be..8663fb889 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -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 \n" + "using IntrusivePtr = boost::intrusive_ptr;\n" + "template class Vertex { };\n" + "IntrusivePtr> p;"; + const char expected[] = "; " + "class Vertex ; " + "boost :: intrusive_ptr < Vertex > p ;" + "class Vertex { } ;"; + 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);