#7027 TokenList::validateAst() did not detect broken AST with endless recursion

This commit is contained in:
Alexander Mai 2016-01-31 22:16:58 +01:00
parent f8de6a66ca
commit a288d5eb16
2 changed files with 17 additions and 6 deletions

View File

@ -1098,7 +1098,7 @@ void TokenList::createAst()
void TokenList::validateAst() void TokenList::validateAst()
{ {
std::set < const Token* > astTokens; std::set < const Token* > safeAstTokens;
// Verify that ast looks ok // Verify that ast looks ok
for (const Token *tok = _front; tok; tok = tok->next()) { for (const Token *tok = _front; tok; tok = tok->next()) {
// Syntax error if binary operator only has 1 operand // Syntax error if binary operator only has 1 operand
@ -1111,14 +1111,15 @@ void TokenList::validateAst()
// check for endless recursion // check for endless recursion
const Token* parent=tok; const Token* parent=tok;
std::set < const Token* > astTokens;
while ((parent = parent->astParent()) != nullptr) { while ((parent = parent->astParent()) != nullptr) {
if (parent==tok) if (safeAstTokens.find(parent)!= safeAstTokens.end())
throw InternalError(tok, "AST broken: endless recursion from '" + tok->str() + "'", InternalError::SYNTAX);
if (astTokens.find(parent)!= astTokens.end()) {
break; break;
} if (astTokens.find(parent)!= astTokens.end())
throw InternalError(tok, "AST broken: endless recursion from '" + tok->str() + "'", InternalError::SYNTAX);
astTokens.insert(parent); astTokens.insert(parent);
} }
safeAstTokens.insert(astTokens.begin(), astTokens.end());
} }
} }
@ -1136,7 +1137,7 @@ bool TokenList::validateToken(const Token* tok) const
{ {
if (!tok) if (!tok)
return true; return true;
for (Token *t = _front; t; t = t->next()) { for (const Token *t = _front; t; t = t->next()) {
if (tok==t) if (tok==t)
return true; return true;
} }

View File

@ -223,6 +223,7 @@ private:
TEST_CASE(garbageCode172); TEST_CASE(garbageCode172);
TEST_CASE(garbageCode173); // #6781 TEST_CASE(garbageCode173); // #6781
TEST_CASE(garbageCode174); // #7356 TEST_CASE(garbageCode174); // #7356
TEST_CASE(garbageCode175);
TEST_CASE(garbageValueFlow); TEST_CASE(garbageValueFlow);
TEST_CASE(garbageSymbolDatabase); TEST_CASE(garbageSymbolDatabase);
TEST_CASE(garbageAST); TEST_CASE(garbageAST);
@ -1464,6 +1465,15 @@ private:
void garbageCode174() { // #7356 void garbageCode174() { // #7356
checkCode("{r e() { w*constD = (())D = cast< }}"); checkCode("{r e() { w*constD = (())D = cast< }}");
} }
void garbageCode175() { // #7027
ASSERT_THROW(checkCode("int f() {\n"
" int i , j;\n"
" for ( i = t3 , i < t1 ; i++ )\n"
" for ( j = 0 ; j < = j++ )\n"
" return t1 ,\n"
"}"), InternalError);
}
}; };
REGISTER_TEST(TestGarbage) REGISTER_TEST(TestGarbage)