Fixed #7724 (hang: long expression => wrong AST)

This commit is contained in:
Daniel Marjamäki 2017-06-04 12:16:49 +02:00
parent 4c62190e32
commit 26bd863d0a
2 changed files with 68 additions and 2 deletions

View File

@ -3805,8 +3805,8 @@ bool Tokenizer::simplifyTokenList2()
Token::assignProgressValues(list.front()); Token::assignProgressValues(list.front());
list.createAst(); list.createAst();
// skipping this here may help improve performance. Might be enabled later on demand. #7208 // needed for #7208 (garbage code) and #7724 (ast max depth limit)
// list.validateAst(); list.validateAst();
// Create symbol database and then remove const keywords // Create symbol database and then remove const keywords
createSymbolDatabase(); createSymbolDatabase();

View File

@ -445,6 +445,7 @@ private:
// AST data // AST data
TEST_CASE(astexpr); TEST_CASE(astexpr);
TEST_CASE(astexpr2); // limit large expressions
TEST_CASE(astpar); TEST_CASE(astpar);
TEST_CASE(astnewdelete); TEST_CASE(astnewdelete);
TEST_CASE(astbrackets); TEST_CASE(astbrackets);
@ -7866,6 +7867,8 @@ private:
tokenList.prepareTernaryOpForAST(); tokenList.prepareTernaryOpForAST();
tokenList.list.createAst(); tokenList.list.createAst();
tokenList.list.validateAst();
// Basic AST validation // Basic AST validation
for (const Token *tok = tokenList.list.front(); tok; tok = tok->next()) { for (const Token *tok = tokenList.list.front(); tok; tok = tok->next()) {
if (tok->astOperand2() && !tok->astOperand1() && tok->str() != ";" && tok->str() != ":") if (tok->astOperand2() && !tok->astOperand1() && tok->str() != ";" && tok->str() != ":")
@ -7987,6 +7990,69 @@ private:
ASSERT_EQUALS("ifCA_FarReadfilenew(,sizeofobjtype(,(!(", testAst("if (!CA_FarRead(file, (void far *)new, sizeof(objtype)))")); // #5910 - don't hang if C code is parsed as C++ ASSERT_EQUALS("ifCA_FarReadfilenew(,sizeofobjtype(,(!(", testAst("if (!CA_FarRead(file, (void far *)new, sizeof(objtype)))")); // #5910 - don't hang if C code is parsed as C++
} }
void astexpr2() { // limit for large expressions
// #7724 - wrong AST causes hang
// Ideally a proper AST is created for this code.
const char code[] = "const char * a(int type) {\n"
" return (\n"
" (type == 1) ? \"\"\n"
" : (type == 2) ? \"\"\n"
" : (type == 3) ? \"\"\n"
" : (type == 4) ? \"\"\n"
" : (type == 5) ? \"\"\n"
" : (type == 6) ? \"\"\n"
" : (type == 7) ? \"\"\n"
" : (type == 8) ? \"\"\n"
" : (type == 9) ? \"\"\n"
" : (type == 10) ? \"\"\n"
" : (type == 11) ? \"\"\n"
" : (type == 12) ? \"\"\n"
" : (type == 13) ? \"\"\n"
" : (type == 14) ? \"\"\n"
" : (type == 15) ? \"\"\n"
" : (type == 16) ? \"\"\n"
" : (type == 17) ? \"\"\n"
" : (type == 18) ? \"\"\n"
" : (type == 19) ? \"\"\n"
" : (type == 20) ? \"\"\n"
" : (type == 21) ? \"\"\n"
" : (type == 22) ? \"\"\n"
" : (type == 23) ? \"\"\n"
" : (type == 24) ? \"\"\n"
" : (type == 25) ? \"\"\n"
" : (type == 26) ? \"\"\n"
" : (type == 27) ? \"\"\n"
" : (type == 28) ? \"\"\n"
" : (type == 29) ? \"\"\n"
" : (type == 30) ? \"\"\n"
" : (type == 31) ? \"\"\n"
" : (type == 32) ? \"\"\n"
" : (type == 33) ? \"\"\n"
" : (type == 34) ? \"\"\n"
" : (type == 35) ? \"\"\n"
" : (type == 36) ? \"\"\n"
" : (type == 37) ? \"\"\n"
" : (type == 38) ? \"\"\n"
" : (type == 39) ? \"\"\n"
" : (type == 40) ? \"\"\n"
" : (type == 41) ? \"\"\n"
" : (type == 42) ? \"\"\n"
" : (type == 43) ? \"\"\n"
" : (type == 44) ? \"\"\n"
" : (type == 45) ? \"\"\n"
" : (type == 46) ? \"\"\n"
" : (type == 47) ? \"\"\n"
" : (type == 48) ? \"\"\n"
" : (type == 49) ? \"\"\n"
" : (type == 50) ? \"\"\n"
" : (type == 51) ? \"\"\n"
" : \"\");\n"
"}\n";
// Ensure that the AST is validated for the simplified token list
tokenizeAndStringify(code); // this does not crash/hang
ASSERT_THROW(tokenizeAndStringify(code,true), InternalError); // when parentheses are simplified the AST will be wrong
}
void astnewdelete() { void astnewdelete() {
ASSERT_EQUALS("aintnew=", testAst("a = new int;")); ASSERT_EQUALS("aintnew=", testAst("a = new int;"));
ASSERT_EQUALS("aint4[new=", testAst("a = new int[4];")); ASSERT_EQUALS("aint4[new=", testAst("a = new int[4];"));