From 2108251851d11a4f19004e5e3192ef6784673ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 28 Jan 2014 06:11:53 +0100 Subject: [PATCH] Fixed #5417 (ast: avoid hang when '({})' is used) --- lib/tokenlist.cpp | 9 ++++++++- test/testtokenize.cpp | 5 +++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index dbd0530dc..58ab099d7 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -747,16 +747,23 @@ static Token * createAstAtToken(Token *tok) 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%|( !!{")) { std::stack operands; Token * const tok1 = tok; compileExpression(tok, operands); Token * const endToken = tok; + if (endToken == tok1) + return tok1; // 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, "( {")) continue; + if (tok->next() == endToken) + break; const Token * const endToken2 = tok->linkAt(1); for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : NULL) tok = createAstAtToken(tok); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index aaef4073a..e122427fa 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -10052,9 +10052,9 @@ private: // Set links.. std::stack links; for (Token *tok = tokenList.front(); tok; tok = tok->next()) { - if (Token::Match(tok, "(|[")) + if (Token::Match(tok, "(|[|{")) links.push(tok); - else if (!links.empty() && Token::Match(tok,")|]")) { + else if (!links.empty() && Token::Match(tok,")|]|}")) { Token::createMutualLinks(links.top(), tok); links.pop(); } else if (Token::Match(tok, "< %type% >")) { @@ -10118,6 +10118,7 @@ private: 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( 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