From 5976faaaf54b83bc4e9bad03e7b26ea9b6f948f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 5 Jun 2023 20:43:17 +0200 Subject: [PATCH] Fixed #11745 (Fix AST for 'new type..[..]{..}') (#5118) --- lib/tokenlist.cpp | 27 ++++++++++++++++++++++++--- test/testtokenize.cpp | 1 + 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 4519fa9e9..04eb4fae2 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -779,7 +779,7 @@ static void compileTerm(Token *&tok, AST_state& state) prev = prev->link()->previous(); if (Token::simpleMatch(tok->link(),"} [")) { tok = tok->next(); - } else if (state.cpp && iscpp11init(tok)) { + } else if ((state.cpp && iscpp11init(tok)) || Token::simpleMatch(tok->previous(), "] {")) { Token *const end = tok->link(); if (state.op.empty() || Token::Match(tok->previous(), "[{,]") || Token::Match(tok->tokAt(-2), "%name% (")) { if (Token::Match(tok, "{ . %name% =|{")) { @@ -849,6 +849,17 @@ static void compileScope(Token *&tok, AST_state& state) static bool isPrefixUnary(const Token* tok, bool cpp) { + if (cpp && Token::simpleMatch(tok->previous(), "* [") && Token::simpleMatch(tok->link(), "] {")) { + for (const Token* prev = tok->previous(); Token::Match(prev, "%name%|::|*|&|>|>>"); prev = prev->previous()) { + if (Token::Match(prev, ">|>>")) { + if (!prev->link()) + break; + prev = prev->link(); + } + if (prev->str() == "new") + return false; + } + } if (!tok->previous() || ((Token::Match(tok->previous(), "(|[|{|%op%|;|?|:|,|.|return|::") || (cpp && tok->strAt(-1) == "throw")) && (tok->previous()->tokType() != Token::eIncDecOp || tok->tokType() == Token::eIncDecOp))) @@ -944,8 +955,18 @@ static void compilePrecedence2(Token *&tok, AST_state& state) } Token* const tok2 = tok; - if (tok->strAt(1) != "]") + if (tok->strAt(1) != "]") { compileBinOp(tok, state, compileExpression); + if (Token::Match(tok2->previous(), "%type%|* [") && Token::Match(tok, "] { !!}")) { + tok = tok->next(); + Token* const tok3 = tok; + compileBinOp(tok, state, compileExpression); + if (tok != tok3->link()) + throw InternalError(tok, "Syntax error in {..}", InternalError::AST); + tok = tok->next(); + continue; + } + } else compileUnaryOp(tok, state, compileExpression); tok = tok2->link()->next(); @@ -1072,7 +1093,7 @@ static void compilePrecedence3(Token *&tok, AST_state& state) state.op.push(tok->next()); tok = tok->link()->next(); compileBinOp(tok, state, compilePrecedence2); - } else if (tok && (tok->str() == "[" || tok->str() == "(" || tok->str() == "{")) + } else if (Token::Match(tok, "(|{|[")) compilePrecedence2(tok, state); else if (innertype && Token::simpleMatch(tok, ") [")) { tok = tok->next(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 336753ee1..db83f947e 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -6166,6 +6166,7 @@ private: ASSERT_EQUALS("intnewdelete", testAst("delete new int;")); // #11039 ASSERT_EQUALS("intnewdelete", testAst("void f() { delete new int; }")); ASSERT_EQUALS("pint3[new1+=", testAst("p = (new int[3]) + 1;")); // #11327 + ASSERT_EQUALS("aType2[T1T2,{new=", testAst("a = new Type *[2] {T1, T2};")); // #11745 // placement new ASSERT_EQUALS("X12,3,(new ab,c,", testAst("new (a,b,c) X(1,2,3);"));