From 8c5cf8c02970a8b6e899c387ee3c9fd5f91c1e6b Mon Sep 17 00:00:00 2001 From: IOBYTE Date: Fri, 20 Sep 2019 06:35:01 -0400 Subject: [PATCH] Fixed #9046 syntaxError (#2180) * Fixed #9046 syntaxError * fix another syntax error * fix some more syntax errors --- lib/templatesimplifier.cpp | 3 +- lib/token.cpp | 5 ++-- lib/tokenize.cpp | 5 ++-- test/testsimplifytemplate.cpp | 52 +++++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 640a528a2..4c8555fd0 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -384,7 +384,8 @@ void TemplateSimplifier::checkComplicatedSyntaxErrorsInTemplates() tok3 = tok3->tokAt(2); if (Token::Match(tok3, "%type% <")) inclevel = true; - } + } else if (tok2->strAt(-1) == ">") + syntaxError(tok); if (inclevel) { ++level; diff --git a/lib/token.cpp b/lib/token.cpp index 8b942c4b1..fdc77059b 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -869,9 +869,8 @@ const Token * Token::findClosingBracket() const } else if (Token::Match(closing, "}|]|)|;")) return nullptr; // we can make some guesses for template parameters - else if (closing->str() == "<" && - (!templateParameter || (closing->previous() && closing->previous()->isName() && - templateParameters.find(closing->strAt(-1)) == templateParameters.end()))) + else if (closing->str() == "<" && closing->previous() && closing->previous()->isName() && + (templateParameter ? templateParameters.find(closing->strAt(-1)) == templateParameters.end() : true)) ++depth; else if (closing->str() == ">") { if (--depth == 0) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 754d5671c..53641a26d 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9408,8 +9408,9 @@ void Tokenizer::findGarbageCode() const tok = tok->next()->findClosingBracket(); if (!tok) syntaxError(tok1); - if (!Token::Match(tok, ">|>> ::| %name%") && - !Token::Match(tok, ">|>> [ [ %name%")) + if (!Token::Match(tok, ">|>> ::|...| %name%") && + !Token::Match(tok, ">|>> [ [ %name%") && + !Token::Match(tok, "> >|*")) syntaxError(tok->next() ? tok->next() : tok1); } } diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index 215412f65..8da4521e8 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -181,6 +181,10 @@ private: TEST_CASE(template141); // #9337 TEST_CASE(template142); // #9338 TEST_CASE(template143); + TEST_CASE(template144); // #9046 + TEST_CASE(template145); // syntax error + TEST_CASE(template146); // syntax error + TEST_CASE(template147); // syntax error 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) @@ -3479,6 +3483,54 @@ private: ASSERT_EQUALS(exp, tok(code)); } + void template144() { // #9046 + const char code[] = "namespace a {\n" + "template \n" + "struct promote {\n" + " using type = T;\n" + "};\n" + "template \n" + "struct promote ::value && sizeof(T) < sizeof(int) >::type>{\n" + "};\n" + "}"; + const char exp[] = "namespace a { " + "template < typename T , typename enable = void > " + "struct promote { " + "using type = T ; " + "} ; " + "template < typename T > " + "struct promote < T , std :: enable_if < std :: is_integral < T > :: value && sizeof ( T ) < sizeof ( int ) > :: type > { " + "} ; " + "}"; + ASSERT_EQUALS(exp, tok(code)); + } + + void template145() { // syntax error + const char code[] = "template class ...Cs, Cs ...Vs> struct B { };"; + const char exp[] = "template < template < typename , Ts = 0 > class ... Cs , Cs < Ts > ... Vs > struct B { } ;"; + ASSERT_EQUALS(exp, tok(code)); + } + + void template146() { // syntax error + const char code[] = "template struct C { };\n" + "template class TT_TT> class TT, class U = TT >\n" + "struct S {\n" + " void foo(TT);\n" + "};"; + const char exp[] = "template < class T > struct C { } ; " + "template < class T , template < class TT_T0 , template < class TT_T1 > class TT_TT > class TT , class U = TT < int , C > > " + "struct S { " + "void foo ( TT < T , C > ) ; " + "} ;"; + ASSERT_EQUALS(exp, tok(code)); + } + + void template147() { // syntax error + const char code[] = "template