From 0e4efea5304079a346088d8a0a0c56010f019758 Mon Sep 17 00:00:00 2001 From: IOBYTE Date: Thu, 12 Dec 2019 14:50:20 -0500 Subject: [PATCH] fix #9539 (Syntax error for valid C++14 code) (#2446) --- lib/templatesimplifier.cpp | 2 +- lib/tokenize.cpp | 4 ++-- test/testsimplifytemplate.cpp | 34 ++++++++++++++++++++++++++++------ 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 653136f06..69ee96d16 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -824,7 +824,7 @@ void TemplateSimplifier::getTemplateInstantiations() Token *tok2 = Token::findsimplematch(tok->tokAt(2), ";"); if (tok2) tok = tok2; - } else if (Token::Match(tok->previous(), "(|{|}|;|=|>|<<|:|.|*|&|return|<|,|! %name% ::|<|(") || + } else if (Token::Match(tok->previous(), "(|{|}|;|=|>|<<|:|.|*|&|return|<|,|!|[ %name% ::|<|(") || Token::Match(tok->previous(), "%type% %name% ::|<") || Token::Match(tok->tokAt(-2), "[,:] private|protected|public %name% ::|<")) { std::string scopeName = tok->scopeInfo()->name; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 08b7fbd54..b3a332632 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9347,7 +9347,7 @@ void Tokenizer::findGarbageCode() const prev = prev->previous(); if (Token::Match(prev, "%op%|%num%|%str%|%char%")) { if (!Token::simpleMatch(tok->tokAt(-2), "operator \"\" if") && - !Token::simpleMatch(tok->tokAt(-2), "extern \"C\"") ) + !Token::simpleMatch(tok->tokAt(-2), "extern \"C\"")) syntaxError(tok, prev == tok->previous() ? (prev->str() + " " + tok->str()) : (prev->str() + " .. " + tok->str())); } } @@ -9448,7 +9448,7 @@ void Tokenizer::findGarbageCode() const syntaxError(tok); if (Token::Match(tok, ";|(|[ %comp%")) syntaxError(tok); - if (Token::Match(tok, "%cop%|= ]") && !(isCPP() && Token::Match(tok->previous(), "[|, &|= ]"))) + if (Token::Match(tok, "%cop%|= ]") && !(isCPP() && Token::Match(tok->previous(), "[|,|%num% &|=|> ]"))) syntaxError(tok); if (Token::Match(tok, "[+-] [;,)]}]") && !(isCPP() && Token::Match(tok->previous(), "operator [+-] ;"))) syntaxError(tok); diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index 0b064d6c1..9316a6bf9 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -192,6 +192,7 @@ private: TEST_CASE(template152); // #9467 TEST_CASE(template153); // #9483 TEST_CASE(template154); // #9495 + TEST_CASE(template155); // #9539 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) @@ -2799,12 +2800,6 @@ private: ASSERT_EQUALS(exp, tok(code)); } - void template154() { // #9495 - const char code[] = "template ::value), int>> void i(S s);"; - const char exp[] = "template < typename S , enable_if_t < ( is_compile_string < S > :: value ) , int > > void i ( S s ) ;"; - ASSERT_EQUALS(exp, tok(code)); - } - void template116() { // #9178 { const char code[] = "template auto b() -> decltype(a{}.template b);\n" @@ -3666,6 +3661,33 @@ private: ASSERT_EQUALS(exp, tok(code)); } + void template154() { // #9495 + const char code[] = "template ::value), int>> void i(S s);"; + const char exp[] = "template < typename S , enable_if_t < ( is_compile_string < S > :: value ) , int > > void i ( S s ) ;"; + ASSERT_EQUALS(exp, tok(code)); + } + + void template155() { // #9539 + const char code[] = "template int a = 0;\n" + "struct b {\n" + " void operator[](int);\n" + "};\n" + "void c() {\n" + " b d;\n" + " d[a<0>];\n" + "}"; + const char exp[] = "int a<0> ; " + "a<0> = 0 ; " + "struct b { " + "void operator[] ( int ) ; " + "} ; " + "void c ( ) { " + "b d ; " + "d [ a<0> ] ; " + "}"; + 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"