From 4b231c53a4d5df7d57493a279716813ecd1ed4ba Mon Sep 17 00:00:00 2001 From: IOBYTE Date: Tue, 20 Aug 2019 14:25:18 -0400 Subject: [PATCH] Fixed #9287 and #9288 (Syntax error on valid C++ code) (#2104) --- lib/tokenize.cpp | 4 +++- test/testsimplifytemplate.cpp | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 8573f6ea6..ecb2a0dfd 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3476,6 +3476,8 @@ void Tokenizer::setVarIdPass1() continue; if (tok->next() && tok->next()->str() == "::") continue; + if (Token::simpleMatch(tok->tokAt(-2), ":: template")) + continue; } // function declaration inside executable scope? Function declaration is of form: type name "(" args ")" @@ -3943,7 +3945,7 @@ void Tokenizer::createLinks2() while (!type.empty() && type.top()->str() == "<") { const Token* end = type.top()->findClosingBracket(); - if (Token::Match(end, "> %comp%|;|.|=")) + if (Token::Match(end, "> %comp%|;|.|=|{")) break; // Variable declaration if (Token::Match(end, "> %var% ;") && (type.top()->tokAt(-2) == nullptr || Token::Match(type.top()->tokAt(-2), ";|}|{"))) diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index 745d3ac03..61213b7d1 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -173,6 +173,8 @@ private: TEST_CASE(template133); TEST_CASE(template134); TEST_CASE(template135); + TEST_CASE(template136); // #9287 + TEST_CASE(template137); // #9288 TEST_CASE(template_specialization_1); // #7868 - template specialization template struct S> {..}; TEST_CASE(template_specialization_2); // #7868 - template specialization template struct S> {..}; TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template) @@ -3230,6 +3232,48 @@ private: ASSERT_EQUALS(exp, tok(code)); } + void template136() { // #9287 + const char code[] = "namespace a {\n" + "template struct b;\n" + "template struct c;\n" + "template struct d;\n" + "template struct f;\n" + "template struct g;\n" + "template \n" + "struct i : c>::k && b>::k> {};\n" + "}\n" + "namespace hana = a;\n" + "using e = int;\n" + "void l(hana::d>);"; + const char exp[] = "namespace a { " + "template < typename > struct b ; " + "template < int > struct c ; " + "template < typename > struct d ; " + "template < typename > struct f ; " + "template < typename > struct g ; " + "struct i ; " + "} " + "void l ( a :: d < a :: i > ) ; " + "struct a :: i : c < b < f < int :: j > > :: k && b < g < int :: j > > :: k > { } ;"; + ASSERT_EQUALS(exp, tok(code)); + } + + void template137() { // #9288 + const char code[] = "template struct a;\n" + "template using c = typename a::d;\n" + "template class, class> struct e;\n" + "template \n" + "using i = typename e::d;\n" + "template struct k : c::template fn {};"; + const char exp[] = "template < bool > struct a ; " + "template < bool b , class > using c = typename a < b > :: d ; " + "template < class , template < class > class , class > struct e ; " + "template < class f , class g , class . . . h > " + "using i = typename e < f , g :: template fn , h . . . > :: d ; " + "template < class . . . j > struct k : c < sizeof . . . ( j ) , int > :: template fn < j . . . > { } ;"; + ASSERT_EQUALS(exp, tok(code)); + } + void template_specialization_1() { // #7868 - template specialization template struct S> {..}; const char code[] = "template struct C {};\n" "template struct S {a};\n"