Fixed #8006 (AST: Wrong tree with complex for loops and casts)

This commit is contained in:
Daniel Marjamäki 2017-04-17 21:11:53 +02:00
parent ce9f121ce6
commit bb015c6a2b
2 changed files with 24 additions and 13 deletions

View File

@ -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<Token *>(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<Token*>(init->astTop()));
tok2 = semicolon1->next();
while (tok2 != semicolon2 && !tok2->isName() && !tok2->isNumber())
tok2 = tok2->next();
if (tok2 != semicolon2)
semicolon2->astOperand1(const_cast<Token*>(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<Token*>(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<Token*>(state3.op.top()));

View File

@ -7951,6 +7951,7 @@ private:
ASSERT_EQUALS("forcd:(", testAst("for (a<b> c : d);"));
ASSERT_EQUALS("forde:(", testAst("for (a::b<c> d : e);"));
ASSERT_EQUALS("forx*0=yz;;(", testAst("for(*x=0;y;z)"));
ASSERT_EQUALS("forx0=y(8<z;;(", testAst("for (x=0;(int)y<8;z);"));
// problems with multiple expressions
ASSERT_EQUALS("ax( whilex(", testAst("a(x) while (x)"));