Fixed #5417 (ast: avoid hang when '({})' is used)

This commit is contained in:
Daniel Marjamäki 2014-01-28 06:11:53 +01:00
parent b8b573321e
commit 2108251851
2 changed files with 11 additions and 3 deletions

View File

@ -747,16 +747,23 @@ static Token * createAstAtToken(Token *tok)
return tok->linkAt(1); return tok->linkAt(1);
} }
if (Token::simpleMatch(tok, "( {"))
return tok;
if (tok->str() == "return" || !tok->previous() || Token::Match(tok, "%var% %op%|(|[|.|=|::") || Token::Match(tok->previous(), "[;{}] %cop%|( !!{")) { if (tok->str() == "return" || !tok->previous() || Token::Match(tok, "%var% %op%|(|[|.|=|::") || Token::Match(tok->previous(), "[;{}] %cop%|( !!{")) {
std::stack<Token *> operands; std::stack<Token *> operands;
Token * const tok1 = tok; Token * const tok1 = tok;
compileExpression(tok, operands); compileExpression(tok, operands);
Token * const endToken = tok; Token * const endToken = tok;
if (endToken == tok1)
return tok1;
// Compile inner expressions inside inner ({..}) // Compile inner expressions inside inner ({..})
for (tok = tok1; tok && tok != endToken; tok = tok ? tok->next() : NULL) { for (tok = tok1->next(); tok && tok != endToken; tok = tok ? tok->next() : NULL) {
if (!Token::simpleMatch(tok, "( {")) if (!Token::simpleMatch(tok, "( {"))
continue; continue;
if (tok->next() == endToken)
break;
const Token * const endToken2 = tok->linkAt(1); const Token * const endToken2 = tok->linkAt(1);
for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : NULL) for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : NULL)
tok = createAstAtToken(tok); tok = createAstAtToken(tok);

View File

@ -10052,9 +10052,9 @@ private:
// Set links.. // Set links..
std::stack<Token *> links; std::stack<Token *> links;
for (Token *tok = tokenList.front(); tok; tok = tok->next()) { for (Token *tok = tokenList.front(); tok; tok = tok->next()) {
if (Token::Match(tok, "(|[")) if (Token::Match(tok, "(|[|{"))
links.push(tok); links.push(tok);
else if (!links.empty() && Token::Match(tok,")|]")) { else if (!links.empty() && Token::Match(tok,")|]|}")) {
Token::createMutualLinks(links.top(), tok); Token::createMutualLinks(links.top(), tok);
links.pop(); links.pop();
} else if (Token::Match(tok, "< %type% >")) { } else if (Token::Match(tok, "< %type% >")) {
@ -10118,6 +10118,7 @@ private:
ASSERT_EQUALS("ax( whilex(", testAst("a(x) while (x)")); ASSERT_EQUALS("ax( whilex(", testAst("a(x) while (x)"));
ASSERT_EQUALS("ifx( i0= whilei(", testAst("if (x) { ({ int i = 0; while(i); }) };")); ASSERT_EQUALS("ifx( i0= whilei(", testAst("if (x) { ({ int i = 0; while(i); }) };"));
ASSERT_EQUALS("ifx( BUG_ON{!( i0= whilei(", testAst("if (x) { BUG_ON(!({int i=0; while(i);})); }")); ASSERT_EQUALS("ifx( BUG_ON{!( i0= whilei(", testAst("if (x) { BUG_ON(!({int i=0; while(i);})); }"));
ASSERT_EQUALS("v0= while{( v0= while{( v0=", testAst("({ v = 0; }); while (({ v = 0; }) != 0); while (({ v = 0; }) != 0);"));
} }
void astpar() const { // parentheses void astpar() const { // parentheses