From 9ad39ca4c0e5d792c1067d3af148ff52695c5d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 12 Apr 2013 16:38:12 +0200 Subject: [PATCH] Fixed #4544 (Crash with this line : class CD : public CC< class CB< CA > >) --- lib/templatesimplifier.cpp | 23 ++++++++++++++++++++--- test/testsimplifytokens.cpp | 35 +++++++++++++++++++++++++---------- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 2b97893cf..d19d9451f 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -581,7 +581,16 @@ bool TemplateSimplifier::instantiateMatch(const Token *instance, const std::stri return false; if (patternAfter) { - const Token *tok = Token::findsimplematch(instance, ">"); + const Token *tok = instance; + unsigned int indentlevel = 0; + for (tok = instance; tok && (tok->str() != ">" || indentlevel > 0); tok = tok->next()) { + if (Token::Match(tok, "[<,] %var% <") && templateParameters(tok->tokAt(2)) > 0) + ++indentlevel; + if (indentlevel > 0 && tok->str() == ">") + --indentlevel; + if (indentlevel > 0 && tok->str() == ">>") + indentlevel -= (indentlevel > 1) ? 2 : 1; + } if (!tok || !Token::Match(tok->next(), patternAfter)) return false; } @@ -1087,11 +1096,19 @@ bool TemplateSimplifier::simplifyTemplateInstantiations( typeForNewNameStr.clear(); break; } - if (tok3->str() == "<" && templateParameters(tok3) > 0) + if (Token::Match(tok3->tokAt(-2), "[<,] %var% <") && templateParameters(tok3) > 0) ++indentlevel; else if (indentlevel > 0 && Token::Match(tok3, "> [,>]")) --indentlevel; - templateMatchPattern += tok3->str(); + else if (indentlevel > 0 && tok3->str() == ">>") { + if (indentlevel == 1) { + templateMatchPattern += '>'; + typeForNewNameStr += '>'; + break; + } + indentlevel -= 2; + } + templateMatchPattern += (tok3->str() == ">>") ? std::string("> >") : tok3->str(); templateMatchPattern += ' '; if (indentlevel == 0 && Token::Match(tok3->previous(), "[<,]")) typesUsedInTemplateInstantiation.push_back(tok3); diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 9c5c2c8fb..5f7b45b48 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -124,7 +124,7 @@ private: TEST_CASE(template30); // #3529 - template < template < .. TEST_CASE(template31); // #4010 - reference type TEST_CASE(template32); // #3818 - mismatching template not handled well - TEST_CASE(template33); // #3818 - inner templates in template instantiation not handled well + TEST_CASE(template33); // #3818,#4544 - inner templates in template instantiation not handled well TEST_CASE(template34); // #3706 - namespace => hang TEST_CASE(template35); // #4074 - A<'x'> a; TEST_CASE(template36); // #4310 - passing unknown template instantiation as template argument @@ -2214,15 +2214,30 @@ private: } void template33() { - // #3818 - inner templates in template instantiation not handled well - const char code[] = "template struct A { };\n" - "template struct B { };\n" - "template struct C { A > > ab; };\n" - "C c;"; - ASSERT_EQUALS("C c ; " - "struct C { A>> ab ; } " - "struct B> { } " // <- redundant.. but nevermind - "struct A>> { }", tok(code)); + { + // #3818 - inner templates in template instantiation not handled well + const char code[] = "template struct A { };\n" + "template struct B { };\n" + "template struct C { A > > ab; };\n" + "C c;"; + ASSERT_EQUALS("C c ; " + "struct C { A>> ab ; } " + "struct B> { } " // <- redundant.. but nevermind + "struct A>> { } " // <- redundant.. but nevermind + "struct A>> { }", tok(code)); + } + + { + // #4544 + const char code[] = "struct A { };\n" + "template struct B { };\n" + "template struct C { };\n" + "C< B > c;"; + ASSERT_EQUALS("struct A { } ; " + "template < class T > struct B { } ; " // <- redundant.. but nevermind + "C> c ; struct C> { }", + tok(code)); + } } void template34() {