Fixed #5097 (TemplateSimplifier::expandTemplate assertion failure)

This commit is contained in:
Graham Whitted 2014-01-05 19:19:52 +01:00 committed by Daniel Marjamäki
parent 77362fd671
commit 86201c13cb
2 changed files with 15 additions and 1 deletions

View File

@ -620,7 +620,7 @@ bool TemplateSimplifier::instantiateMatch(const Token *instance, const std::stri
if (patternAfter) { if (patternAfter) {
const Token *tok = instance; const Token *tok = instance;
unsigned int indentlevel = 0; 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) if (Token::Match(tok, "[<,] %var% <") && templateParameters(tok->tokAt(2)) > 0)
++indentlevel; ++indentlevel;
if (indentlevel > 0 && tok->str() == ">") if (indentlevel > 0 && tok->str() == ">")

View File

@ -135,6 +135,7 @@ private:
TEST_CASE(template40); // #5055 - template specialization outside struct TEST_CASE(template40); // #5055 - template specialization outside struct
TEST_CASE(template41); // #4710 - const in instantiation not handled perfectly TEST_CASE(template41); // #4710 - const in instantiation not handled perfectly
TEST_CASE(template42); // #4878 - variadic templates 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_unhandled);
TEST_CASE(template_default_parameter); TEST_CASE(template_default_parameter);
TEST_CASE(template_default_type); TEST_CASE(template_default_type);
@ -2367,6 +2368,19 @@ private:
tok(code); tok(code);
} }
void template43() { // #5097 - Assert due to '>>' in 'B<A<C>>' not being treated as end of template instantation
const char code[] = "template <typename T> struct C { };"
"template <typename T> struct D { static int f() { return C<T>::f(); } };"
"template <typename T> inline int f2() { return D<T>::f(); }"
"template <typename T> int f1(int x, T *) { int id = f2<T>(); return id; }"
"template <> struct C < B < A >> {"
" static int f() {"
" return f1 < B < A >> (0, reinterpret_cast< B<A> *>(E<void *>::Int(-1)));"
" }"
"};";
tok(code); // Don't assert
}
void template_default_parameter() { void template_default_parameter() {
{ {