From 661ebd3a961a1ad19b01a1237800e7be5407caf5 Mon Sep 17 00:00:00 2001 From: dummyunit Date: Mon, 3 May 2021 22:40:49 +0300 Subject: [PATCH] Fix AST for brace initialization after decltype() (#3245) Currently sub-expressions like decltype(x){} break AST creation for subsequent tokens in the whole expression. In some cases this triggers validation checks in validateAst() and analysis on the file stops. For example, code like this: int x = decltype(0){} ? 0 : 1; currently produces internalAstError. To fix the issue iscpp11init_impl() was changed to recognize { preceded by decltype(expr) as a start of C++11 brace initialization expression. --- lib/tokenlist.cpp | 2 ++ test/testtokenize.cpp | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index bf99f0180..4f5fed93f 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -651,6 +651,8 @@ static bool iscpp11init_impl(const Token * const tok) } if (!nameToken) return false; + if (nameToken->str() == ")" && Token::simpleMatch(nameToken->link()->previous(), "decltype (")) + return true; if (nameToken->str() == ">" && nameToken->link()) nameToken = nameToken->link()->previous(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index ebd4db14c..c7ddfd897 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -5815,6 +5815,15 @@ private: ASSERT_EQUALS("f1{2{,3{,{x,(", testAst("f({{1},{2},{3}},x);")); ASSERT_EQUALS("a1{ b2{", testAst("auto a{1}; auto b{2};")); ASSERT_EQUALS("var1ab::23,{,{4ab::56,{,{,{", testAst("auto var{{1,a::b{2,3}}, {4,a::b{5,6}}};")); + + // Initialization with decltype(expr) instead of a type + ASSERT_EQUALS("decltypex((", testAst("decltype(x)();")); + ASSERT_EQUALS("decltypex({", testAst("decltype(x){};")); + ASSERT_EQUALS("decltypexy+(yx+(", testAst("decltype(x+y)(y+x);")); + ASSERT_EQUALS("decltypexy+(yx+{", testAst("decltype(x+y){y+x};")); + + // Check that decltype(x){} doesn't break AST creation for subsequent tokens. + ASSERT_EQUALS("decltypex({01:?", testAst("decltype(x){} ? 0 : 1;")); } void astbrackets() { // []