From bb015c6a2b68615c0e77e8ccef361d8b69dbaa21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 17 Apr 2017 21:11:53 +0200 Subject: [PATCH] Fixed #8006 (AST: Wrong tree with complex for loops and casts) --- lib/tokenlist.cpp | 36 +++++++++++++++++++++++------------- test/testtokenize.cpp | 1 + 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 2032d3e1b..5cf01abd9 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1066,6 +1066,22 @@ static void createAstAtTokenInner(Token * const tok1, const Token *endToken, boo } } +static Token * findAstTop(Token *tok1, Token *tok2) { + for (Token *tok = tok1; tok && (tok != tok2); tok = tok->next()) { + if (tok->astParent() || tok->astOperand1() || tok->astOperand2()) + return const_cast(tok->astTop()); + if (Token::simpleMatch(tok, "( {")) + tok = tok->link(); + } + for (Token *tok = tok1; tok && (tok != tok2); tok = tok->next()) { + if (tok->isName() || tok->isNumber()) + return tok; + if (Token::simpleMatch(tok, "( {")) + tok = tok->link(); + } + return nullptr; +} + static Token * createAstAtToken(Token *tok, bool cpp) { if (Token::simpleMatch(tok, "for (")) { @@ -1083,7 +1099,7 @@ static Token * createAstAtToken(Token *tok, bool cpp) compileExpression(tok2, state1); if (Token::Match(tok2, ";|)")) break; - init1 = 0; + init1 = nullptr; } if (!tok2) // #7109 invalid code return nullptr; @@ -1118,18 +1134,12 @@ static Token * createAstAtToken(Token *tok, bool cpp) if (init != semicolon1) semicolon1->astOperand1(const_cast(init->astTop())); tok2 = semicolon1->next(); - while (tok2 != semicolon2 && !tok2->isName() && !tok2->isNumber()) - tok2 = tok2->next(); - if (tok2 != semicolon2) - semicolon2->astOperand1(const_cast(tok2->astTop())); - tok2 = endPar; - while (tok2 != semicolon2 && !tok2->isName() && !tok2->isNumber()) { - if (Token::simpleMatch(tok2, "} )")) - tok2 = tok2->link(); - tok2 = tok2->previous(); - } - if (tok2 != semicolon2) - semicolon2->astOperand2(const_cast(tok2->astTop())); + tok2 = findAstTop(semicolon1->next(), semicolon2); + if (tok2) + semicolon2->astOperand1(tok2); + tok2 = findAstTop(semicolon2->next(), endPar); + if (tok2) + semicolon2->astOperand2(tok2); else if (!state3.op.empty()) semicolon2->astOperand2(const_cast(state3.op.top())); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index be28723bd..c0e337e88 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -7951,6 +7951,7 @@ private: ASSERT_EQUALS("forcd:(", testAst("for (a c : d);")); ASSERT_EQUALS("forde:(", testAst("for (a::b d : e);")); ASSERT_EQUALS("forx*0=yz;;(", testAst("for(*x=0;y;z)")); + ASSERT_EQUALS("forx0=y(8