From 4ec12209dc3d2c665bd2f99ba9939820e231438b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 8 Aug 2012 06:43:41 +0200 Subject: [PATCH] TemplateSimplifier: Fixed wrong match when inner template parameters are wrongly counted (#3818) --- lib/templatesimplifier.cpp | 7 ++++++- test/testsimplifytokens.cpp | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index b58e26926..baac0b051 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -1013,6 +1013,7 @@ bool TemplateSimplifier::simplifyTemplateInstantions( std::vector typesUsedInTemplateInstantion; std::string typeForNewNameStr; std::string templateMatchPattern(name + " < "); + unsigned int indentlevel = 0; for (const Token *tok3 = tok2->tokAt(2); tok3 && tok3->str() != ">"; tok3 = tok3->next()) { // #2648 - unhandled parenthesis => bail out // #2721 - unhandled [ => bail out @@ -1024,9 +1025,13 @@ bool TemplateSimplifier::simplifyTemplateInstantions( typeForNewNameStr.clear(); break; } + if (tok3->str() == "<" && templateParameters(tok3) > 0) + ++indentlevel; + else if (indentlevel > 0 && Token::simpleMatch(tok3, "> ,")) + --indentlevel; templateMatchPattern += tok3->str(); templateMatchPattern += " "; - if (Token::Match(tok3->previous(), "[<,]")) + if (indentlevel == 0 && Token::Match(tok3->previous(), "[<,]")) typesUsedInTemplateInstantion.push_back(tok3); // add additional type information if (tok3->isUnsigned()) diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index ce0c5616f..832d35c29 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -125,6 +125,7 @@ private: TEST_CASE(template29); // #3449 - don't crash for garbage code TEST_CASE(template30); // #3529 - template < template < .. TEST_CASE(template31); // #4010 - reference type + TEST_CASE(template32); // #3818 - mismatching template not handled well TEST_CASE(template_unhandled); TEST_CASE(template_default_parameter); TEST_CASE(template_default_type); @@ -2153,6 +2154,23 @@ private: ASSERT_EQUALS("A a ; struct A { }", tok(code)); } + void template32() { + // #3818 - mismatching template not handled well + const char code[] = "template struct A { };\n" + "\n" + "template \n" + "struct B\n" + "{\n" + " public:\n" + " A < int, Pair, int > a;\n" // mismatching parameters => don't instantiate + "};\n" + "\n" + "B b;\n"; + ASSERT_EQUALS("template < class T1 , class T2 , class T3 , class T4 > struct A { } ; " + "B b ; " + "struct B { public: A < int , Pair < int , int > , int > a ; }", tok(code)); + } + void template_unhandled() { // An unhandled template usage should be simplified.. ASSERT_EQUALS("x ( ) ;", tok("x();"));