Fixed #7934 (Wrong AST for 'for (i=0;cond;({min(x,10);}))')
This commit is contained in:
parent
7c0aa4464c
commit
c18fe8262b
|
@ -998,6 +998,39 @@ static bool isLambdaCaptureList(const Token * tok)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Token * createAstAtToken(Token *tok, bool cpp);
|
||||||
|
|
||||||
|
// Compile inner expressions inside inner ({..}) and lambda bodies
|
||||||
|
static void createAstAtTokenInner(Token * const tok1, const Token *endToken, bool cpp)
|
||||||
|
{
|
||||||
|
for (Token *tok = tok1; tok && tok != endToken; tok = tok ? tok->next() : nullptr) {
|
||||||
|
if (tok->str() == "{") {
|
||||||
|
if (Token::simpleMatch(tok->previous(), "( {"))
|
||||||
|
;
|
||||||
|
else if (Token::simpleMatch(tok->astParent(), "(") &&
|
||||||
|
Token::simpleMatch(tok->astParent()->astParent(), "[") &&
|
||||||
|
tok->astParent()->astParent()->astOperand1() &&
|
||||||
|
tok == tok->astParent()->astParent()->astOperand1()->astOperand1())
|
||||||
|
;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (Token::simpleMatch(tok->previous(), "( { ."))
|
||||||
|
break;
|
||||||
|
|
||||||
|
const Token * const endToken2 = tok->link();
|
||||||
|
for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : nullptr)
|
||||||
|
tok = createAstAtToken(tok, cpp);
|
||||||
|
} else if (tok->str() == "[") {
|
||||||
|
if (isLambdaCaptureList(tok)) {
|
||||||
|
const Token * const endToken2 = tok->link();
|
||||||
|
for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : nullptr)
|
||||||
|
tok = createAstAtToken(tok, cpp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Token * createAstAtToken(Token *tok, bool cpp)
|
static Token * createAstAtToken(Token *tok, bool cpp)
|
||||||
{
|
{
|
||||||
if (Token::simpleMatch(tok, "for (")) {
|
if (Token::simpleMatch(tok, "for (")) {
|
||||||
|
@ -1041,6 +1074,10 @@ static Token * createAstAtToken(Token *tok, bool cpp)
|
||||||
return nullptr; // invalid code #7235
|
return nullptr; // invalid code #7235
|
||||||
tok2 = tok2->next();
|
tok2 = tok2->next();
|
||||||
AST_state state3(cpp);
|
AST_state state3(cpp);
|
||||||
|
if (Token::simpleMatch(tok2, "( {")) {
|
||||||
|
state3.op.push(tok2->next());
|
||||||
|
tok2 = tok2->link()->next();
|
||||||
|
}
|
||||||
compileExpression(tok2, state3);
|
compileExpression(tok2, state3);
|
||||||
|
|
||||||
if (init != semicolon1)
|
if (init != semicolon1)
|
||||||
|
@ -1051,15 +1088,22 @@ static Token * createAstAtToken(Token *tok, bool cpp)
|
||||||
if (tok2 != semicolon2)
|
if (tok2 != semicolon2)
|
||||||
semicolon2->astOperand1(const_cast<Token*>(tok2->astTop()));
|
semicolon2->astOperand1(const_cast<Token*>(tok2->astTop()));
|
||||||
tok2 = endPar;
|
tok2 = endPar;
|
||||||
while (tok2 != semicolon2 && !tok2->isName() && !tok2->isNumber())
|
while (tok2 != semicolon2 && !tok2->isName() && !tok2->isNumber()) {
|
||||||
|
if (Token::simpleMatch(tok2, "} )"))
|
||||||
|
tok2 = tok2->link();
|
||||||
tok2 = tok2->previous();
|
tok2 = tok2->previous();
|
||||||
|
}
|
||||||
if (tok2 != semicolon2)
|
if (tok2 != semicolon2)
|
||||||
semicolon2->astOperand2(const_cast<Token*>(tok2->astTop()));
|
semicolon2->astOperand2(const_cast<Token*>(tok2->astTop()));
|
||||||
|
else if (!state3.op.empty())
|
||||||
|
semicolon2->astOperand2(const_cast<Token*>(state3.op.top()));
|
||||||
|
|
||||||
semicolon1->astOperand2(semicolon2);
|
semicolon1->astOperand2(semicolon2);
|
||||||
tok->next()->astOperand1(tok);
|
tok->next()->astOperand1(tok);
|
||||||
tok->next()->astOperand2(semicolon1);
|
tok->next()->astOperand2(semicolon1);
|
||||||
|
|
||||||
|
createAstAtTokenInner(endPar->link(), endPar, cpp);
|
||||||
|
|
||||||
return endPar;
|
return endPar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1080,33 +1124,7 @@ static Token * createAstAtToken(Token *tok, bool cpp)
|
||||||
if (endToken == tok1 || !endToken)
|
if (endToken == tok1 || !endToken)
|
||||||
return tok1;
|
return tok1;
|
||||||
|
|
||||||
// Compile inner expressions inside inner ({..}) and lambda bodies
|
createAstAtTokenInner(tok1->next(), endToken, cpp);
|
||||||
for (tok = tok1->next(); tok && tok != endToken; tok = tok ? tok->next() : nullptr) {
|
|
||||||
if (tok->str() == "{") {
|
|
||||||
if (Token::simpleMatch(tok->previous(), "( {"))
|
|
||||||
;
|
|
||||||
else if (Token::simpleMatch(tok->astParent(), "(") &&
|
|
||||||
Token::simpleMatch(tok->astParent()->astParent(), "[") &&
|
|
||||||
tok->astParent()->astParent()->astOperand1() &&
|
|
||||||
tok == tok->astParent()->astParent()->astOperand1()->astOperand1())
|
|
||||||
;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (Token::simpleMatch(tok->previous(), "( { ."))
|
|
||||||
break;
|
|
||||||
|
|
||||||
const Token * const endToken2 = tok->link();
|
|
||||||
for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : nullptr)
|
|
||||||
tok = createAstAtToken(tok, cpp);
|
|
||||||
} else if (tok->str() == "[") {
|
|
||||||
if (isLambdaCaptureList(tok)) {
|
|
||||||
const Token * const endToken2 = tok->link();
|
|
||||||
for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : nullptr)
|
|
||||||
tok = createAstAtToken(tok, cpp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return endToken ? endToken->previous() : nullptr;
|
return endToken ? endToken->previous() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8033,7 +8033,7 @@ private:
|
||||||
"QT_WA({x=1;},{x=2;});"));
|
"QT_WA({x=1;},{x=2;});"));
|
||||||
ASSERT_EQUALS("xMACROtypeT=value1=,{({=",
|
ASSERT_EQUALS("xMACROtypeT=value1=,{({=",
|
||||||
testAst("x = { MACRO( { .type=T, .value=1 } ) }")); // don't hang: MACRO({..})
|
testAst("x = { MACRO( { .type=T, .value=1 } ) }")); // don't hang: MACRO({..})
|
||||||
|
ASSERT_EQUALS("fori10=i{;;( i--", testAst("for (i=10;i;({i--;}) ) {}"));
|
||||||
|
|
||||||
// function pointer
|
// function pointer
|
||||||
TODO_ASSERT_EQUALS("todo", "va_argapvoid((,(*0=", testAst("*va_arg(ap, void(**) ()) = 0;"));
|
TODO_ASSERT_EQUALS("todo", "va_argapvoid((,(*0=", testAst("*va_arg(ap, void(**) ()) = 0;"));
|
||||||
|
|
Loading…
Reference in New Issue