From 86201c13cbd1a5c415fa11bac3925191c73d6814 Mon Sep 17 00:00:00 2001 From: Graham Whitted Date: Sun, 5 Jan 2014 19:19:52 +0100 Subject: [PATCH] Fixed #5097 (TemplateSimplifier::expandTemplate assertion failure) --- lib/templatesimplifier.cpp | 2 +- test/testsimplifytokens.cpp | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 54462f93c..c0fdcaf9b 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -620,7 +620,7 @@ bool TemplateSimplifier::instantiateMatch(const Token *instance, const std::stri if (patternAfter) { const Token *tok = instance; unsigned int indentlevel = 0; - for (tok = instance; tok && (tok->str() != ">" || indentlevel > 0); tok = tok->next()) { + for (tok = instance; tok && (tok->str() != ">" || indentlevel > 0) && (tok->str() != ">>" || indentlevel > 1); tok = tok->next()) { if (Token::Match(tok, "[<,] %var% <") && templateParameters(tok->tokAt(2)) > 0) ++indentlevel; if (indentlevel > 0 && tok->str() == ">") diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index d076cd44a..ea773fa3f 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -135,6 +135,7 @@ private: TEST_CASE(template40); // #5055 - template specialization outside struct TEST_CASE(template41); // #4710 - const in instantiation not handled perfectly TEST_CASE(template42); // #4878 - variadic templates + TEST_CASE(template43); // #5097 - assert due to '>>' not treated as end of template instantiation TEST_CASE(template_unhandled); TEST_CASE(template_default_parameter); TEST_CASE(template_default_type); @@ -2367,6 +2368,19 @@ private: tok(code); } + void template43() { // #5097 - Assert due to '>>' in 'B>' not being treated as end of template instantation + const char code[] = "template struct C { };" + "template struct D { static int f() { return C::f(); } };" + "template inline int f2() { return D::f(); }" + "template int f1(int x, T *) { int id = f2(); return id; }" + "template <> struct C < B < A >> {" + " static int f() {" + " return f1 < B < A >> (0, reinterpret_cast< B *>(E::Int(-1)));" + " }" + "};"; + tok(code); // Don't assert + } + void template_default_parameter() { {