glsl/glcpp: Fix glcpp to catch garbage after #if 1 ... #else
Previously, a line such as:
#else garbage
would flag an error if it followed "#if 0", but not if it followed "#if 1".
We fix this by setting a new bit of state (lexing_else) that allows the lexer
to defer switching to the <SKIP> start state until after the NEWLINE following
the #else directive.
A new test case is added for:
#if 1
#else garbage
#endif
which was untested before, (and did not generate the desired error).
This fixes the following Khronos GLES3 CTS tests:
tokens_after_else_vertex
tokens_after_else_fragment
Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com>
This commit is contained in:
+13
-12
@@ -137,14 +137,15 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
|
||||
* 2. The skip_stack is NULL meaning that we've reached
|
||||
* the last #endif.
|
||||
*
|
||||
* 3. The lexing_if bit is set. This indicates that we
|
||||
* are lexing the expression following an "#if" of
|
||||
* "#elif". Even inside an "#if 0" we need to lex this
|
||||
* expression so the parser can correctly update the
|
||||
* skip_stack state.
|
||||
* 3. The lexing_directive bit is set. This indicates that we are
|
||||
* lexing a pre-processor directive, (such as #if, #elif, or
|
||||
* #else). For the #if and #elif directives we always need to
|
||||
* parse the conditions, (even if otherwise within an #if
|
||||
* 0). And for #else, we want to be able to generate an error
|
||||
* if any garbage follows #else.
|
||||
*/
|
||||
if (YY_START == INITIAL || YY_START == SKIP) {
|
||||
if (parser->lexing_if ||
|
||||
if (parser->lexing_directive ||
|
||||
parser->skip_stack == NULL ||
|
||||
parser->skip_stack->type == SKIP_NO_SKIP)
|
||||
{
|
||||
@@ -193,25 +194,25 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
|
||||
|
||||
<SKIP,INITIAL>{
|
||||
{HASH}ifdef {
|
||||
yyextra->lexing_if = 1;
|
||||
yyextra->lexing_directive = 1;
|
||||
yyextra->space_tokens = 0;
|
||||
return HASH_IFDEF;
|
||||
}
|
||||
|
||||
{HASH}ifndef {
|
||||
yyextra->lexing_if = 1;
|
||||
yyextra->lexing_directive = 1;
|
||||
yyextra->space_tokens = 0;
|
||||
return HASH_IFNDEF;
|
||||
}
|
||||
|
||||
{HASH}if/[^_a-zA-Z0-9] {
|
||||
yyextra->lexing_if = 1;
|
||||
yyextra->lexing_directive = 1;
|
||||
yyextra->space_tokens = 0;
|
||||
return HASH_IF;
|
||||
}
|
||||
|
||||
{HASH}elif/[^_a-zA-Z0-9] {
|
||||
yyextra->lexing_if = 1;
|
||||
yyextra->lexing_directive = 1;
|
||||
yyextra->space_tokens = 0;
|
||||
return HASH_ELIF;
|
||||
}
|
||||
@@ -348,7 +349,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
|
||||
if (parser->commented_newlines) {
|
||||
BEGIN NEWLINE_CATCHUP;
|
||||
}
|
||||
yyextra->lexing_if = 0;
|
||||
yyextra->lexing_directive = 0;
|
||||
yylineno++;
|
||||
yycolumn = 0;
|
||||
return NEWLINE;
|
||||
@@ -357,7 +358,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
|
||||
/* Handle missing newline at EOF. */
|
||||
<INITIAL><<EOF>> {
|
||||
BEGIN DONE; /* Don't keep matching this rule forever. */
|
||||
yyextra->lexing_if = 0;
|
||||
yyextra->lexing_directive = 0;
|
||||
return NEWLINE;
|
||||
}
|
||||
|
||||
|
||||
@@ -364,7 +364,7 @@ control_line:
|
||||
glcpp_warning(& @1, parser, "ignoring illegal #elif without expression");
|
||||
}
|
||||
}
|
||||
| HASH_ELSE {
|
||||
| HASH_ELSE { parser->lexing_directive = 1; } NEWLINE {
|
||||
if (parser->skip_stack &&
|
||||
parser->skip_stack->has_else)
|
||||
{
|
||||
@@ -376,7 +376,7 @@ control_line:
|
||||
if (parser->skip_stack)
|
||||
parser->skip_stack->has_else = true;
|
||||
}
|
||||
} NEWLINE
|
||||
}
|
||||
| HASH_ENDIF {
|
||||
_glcpp_parser_skip_stack_pop (parser, & @1);
|
||||
} NEWLINE
|
||||
@@ -1211,7 +1211,7 @@ glcpp_parser_create (const struct gl_extensions *extensions, gl_api api)
|
||||
parser->defines = hash_table_ctor (32, hash_table_string_hash,
|
||||
hash_table_string_compare);
|
||||
parser->active = NULL;
|
||||
parser->lexing_if = 0;
|
||||
parser->lexing_directive = 0;
|
||||
parser->space_tokens = 1;
|
||||
parser->newline_as_space = 0;
|
||||
parser->in_control_line = 0;
|
||||
|
||||
@@ -168,7 +168,7 @@ struct glcpp_parser {
|
||||
yyscan_t scanner;
|
||||
struct hash_table *defines;
|
||||
active_list_t *active;
|
||||
int lexing_if;
|
||||
int lexing_directive;
|
||||
int space_tokens;
|
||||
int newline_as_space;
|
||||
int in_control_line;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#if 1
|
||||
#else garbage
|
||||
#endif
|
||||
@@ -0,0 +1,4 @@
|
||||
0:2(7): preprocessor error: syntax error, unexpected IDENTIFIER, expecting NEWLINE
|
||||
0:1(7): preprocessor error: Unterminated #if
|
||||
|
||||
|
||||
Reference in New Issue
Block a user