diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 189f9cd6a..72b5bd44f 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1098,7 +1098,7 @@ void TokenList::createAst() void TokenList::validateAst() { - std::set < const Token* > astTokens; + std::set < const Token* > safeAstTokens; // Verify that ast looks ok for (const Token *tok = _front; tok; tok = tok->next()) { // Syntax error if binary operator only has 1 operand @@ -1111,14 +1111,15 @@ void TokenList::validateAst() // check for endless recursion const Token* parent=tok; + std::set < const Token* > astTokens; while ((parent = parent->astParent()) != nullptr) { - if (parent==tok) - throw InternalError(tok, "AST broken: endless recursion from '" + tok->str() + "'", InternalError::SYNTAX); - if (astTokens.find(parent)!= astTokens.end()) { + if (safeAstTokens.find(parent)!= safeAstTokens.end()) break; - } + if (astTokens.find(parent)!= astTokens.end()) + throw InternalError(tok, "AST broken: endless recursion from '" + tok->str() + "'", InternalError::SYNTAX); astTokens.insert(parent); } + safeAstTokens.insert(astTokens.begin(), astTokens.end()); } } @@ -1136,7 +1137,7 @@ bool TokenList::validateToken(const Token* tok) const { if (!tok) return true; - for (Token *t = _front; t; t = t->next()) { + for (const Token *t = _front; t; t = t->next()) { if (tok==t) return true; } diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index ec39c46fa..e5998d41e 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -223,6 +223,7 @@ private: TEST_CASE(garbageCode172); TEST_CASE(garbageCode173); // #6781 TEST_CASE(garbageCode174); // #7356 + TEST_CASE(garbageCode175); TEST_CASE(garbageValueFlow); TEST_CASE(garbageSymbolDatabase); TEST_CASE(garbageAST); @@ -1464,6 +1465,15 @@ private: void garbageCode174() { // #7356 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)