Commit 315031e3 authored by Nikolai Kosjar's avatar Nikolai Kosjar

GLSL: Avoid infinite loop at error recovery

For error recovery additional tokens are tried to produce a valid
grammar rule.

For the specific case in the bug report

    for(int x=0; x y

the two consecutive identifiers in the end triggered an infinite loop
since the identifier token is also part of those additional tokens that
are tried.

Circumvent this by trying a more conservative list of tokens on the
second try.

Done-by: Erik Verbruggen
Change-Id: I271dddecf947a06ed3af5f9955ee630441533342
Task-number: QTCREATORBUG-18967
Reviewed-by: Erik Verbruggen's avatarErik Verbruggen <erik.verbruggen@qt.io>
Reviewed-by: Nikolai Kosjar's avatarNikolai Kosjar <nikolai.kosjar@qt.io>
parent c354eff5
......@@ -519,9 +519,13 @@ AST *Parser::parse(int startToken)
_recovered = false;
_tos = -1;
_startToken.kind = startToken;
int recoveryAttempts = 0;
do {
again:
recoveryAttempts = 0;
againAfterRecovery:
if (unsigned(++_tos) == _stateStack.size()) {
_stateStack.resize(_tos * 2);
_locationStack.resize(_tos * 2);
......@@ -564,6 +568,7 @@ AST *Parser::parse(int startToken)
reduce(ruleno);
action = nt_action(_stateStack[_tos], lhs[ruleno] - TERMINAL_COUNT);
} else if (action == 0) {
++recoveryAttempts;
const int line = _tokens[yyloc].line + 1;
QString message = QLatin1String("Syntax error");
if (yytoken != -1) {
......@@ -574,7 +579,7 @@ AST *Parser::parse(int startToken)
for (; _tos; --_tos) {
const int state = _stateStack[_tos];
static int tks[] = {
static int tks1[] = {
T_RIGHT_BRACE, T_RIGHT_PAREN, T_RIGHT_BRACKET,
T_SEMICOLON, T_COLON, T_COMMA,
T_NUMBER, T_TYPE_NAME, T_IDENTIFIER,
......@@ -582,6 +587,16 @@ AST *Parser::parse(int startToken)
T_WHILE,
0
};
static int tks2[] = {
T_RIGHT_BRACE, T_RIGHT_PAREN, T_RIGHT_BRACKET,
T_SEMICOLON, T_COLON, T_COMMA,
0
};
int *tks;
if (recoveryAttempts < 2)
tks = tks1;
else
tks = tks2; // Avoid running into an endless loop for e.g.: for(int x=0; x y
for (int *tptr = tks; *tptr; ++tptr) {
const int next = t_action(state, *tptr);
......@@ -604,7 +619,7 @@ AST *Parser::parse(int startToken)
yytoken = -1;
action = next;
goto again;
goto againAfterRecovery;
}
}
}
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment