From f5811c68185a4ef3841ae50b81bda41dc4417c9f Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Sun, 28 Oct 2018 11:16:31 -0500 Subject: [PATCH] Fix issue 8732: Syntax error when using enable_if (#1453) * Fix issue 8732: Syntax error when using enable_if * Fix FPs * Use simpleMatch --- lib/templatesimplifier.cpp | 4 +++- test/testtokenize.cpp | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 5ff8c9c78..dfcbecaaa 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -169,7 +169,9 @@ void TemplateSimplifier::checkComplicatedSyntaxErrorsInTemplates() // parse this statement and see if the '<' and '>' are matching unsigned int level = 0; - for (const Token *tok2 = tok; tok2 && !Token::Match(tok2, "[;{}]"); tok2 = tok2->next()) { + for (const Token *tok2 = tok; tok2 && !Token::simpleMatch(tok2, ";"); tok2 = tok2->next()) { + if(Token::simpleMatch(tok2, "{") && (!Token::Match(tok2->previous(), ">|%type%") || Token::simpleMatch(tok2->link(), "} ;"))) + break; if (tok2->str() == "(") tok2 = tok2->link(); else if (tok2->str() == "<") { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 9fbfb4b6c..836acfb20 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -476,6 +476,7 @@ private: // Make sure the Tokenizer::findGarbageCode() does not have false positives // The TestGarbage ensures that there are true positives TEST_CASE(findGarbageCode); + TEST_CASE(checkEnableIf); // --check-config TEST_CASE(checkConfiguration); @@ -8648,6 +8649,38 @@ private: } + void checkEnableIf() { + ASSERT_NO_THROW(tokenizeAndStringify( + "template<\n" + " typename U,\n" + " typename std::enable_if<\n" + " std::is_convertible{}>::type* = nullptr>\n" + "void foo(U x);\n")) + + ASSERT_NO_THROW(tokenizeAndStringify( + "template\n" + "T f(const T a, const T b) {\n" + " return a < b ? b : a;\n" + "}\n")) + + ASSERT_NO_THROW(tokenizeAndStringify( + "template\n" + "struct A {\n" + " T f(const T a, const T b) {\n" + " return a < b ? b : a;\n" + " }\n" + "};\n")) + + ASSERT_NO_THROW(tokenizeAndStringify( + "const int a = 1;\n" + "const int b = 2;\n" + "template\n" + "struct A {\n" + " int x = a < b ? b : a;" + "};\n")) + + } + void checkConfig(const char code[]) { errout.str("");