#7027 TokenList::validateAst() did not detect broken AST with endless recursion
This commit is contained in:
parent
f8de6a66ca
commit
a288d5eb16
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue