glsl: fixer lexer for unreachable defines
authorTimothy Arceri <tarceri@itsqueeze.com>
Sat, 1 Sep 2018 13:57:38 +0000 (23:57 +1000)
committerTimothy Arceri <tarceri@itsqueeze.com>
Thu, 6 Sep 2018 00:13:21 +0000 (10:13 +1000)
If we have something like:

   #ifdef NOT_DEFINED
   #define A_MACRO(x) \
if (x)
   #endif

The # on the #define is not skipped but the define itself is so
this then gets recognised as #if.

Until 28a3731e3f this didn't happen because we ended up in
<HASH>{NONSPACE} where BEGIN INITIAL was called stopping the
problem from happening.

This change makes sure we never call RETURN_TOKEN_NEVER_SKIP for
if/else/endif when processing a define.

Cc: Ian Romanick <idr@freedesktop.org>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107772
Tested-By: Eero Tamminen <eero.t.tamminen@intel.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/compiler/glsl/glcpp/glcpp-lex.l
src/compiler/glsl/glcpp/glcpp.h

index fe5845acd4e4bbe8323f529885be7dffe7660d02..f7003da0cc84372dd425919e9fcf6a23eb89cbb4 100644 (file)
@@ -289,6 +289,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
          * token. */
        if (parser->first_non_space_token_this_line) {
                BEGIN HASH;
+               yyextra->in_define = false;
        }
 
        RETURN_TOKEN_NEVER_SKIP (HASH_TOKEN);
@@ -336,43 +337,55 @@ HEXADECIMAL_INTEGER       0[xX][0-9a-fA-F]+[uU]?
        /* For the pre-processor directives, we return these tokens
         * even when we are otherwise skipping. */
 <HASH>ifdef {
-       BEGIN INITIAL;
-       yyextra->lexing_directive = 1;
-       yyextra->space_tokens = 0;
-       RETURN_TOKEN_NEVER_SKIP (IFDEF);
+       if (!yyextra->in_define) {
+               BEGIN INITIAL;
+               yyextra->lexing_directive = 1;
+               yyextra->space_tokens = 0;
+               RETURN_TOKEN_NEVER_SKIP (IFDEF);
+       }
 }
 
 <HASH>ifndef {
-       BEGIN INITIAL;
-       yyextra->lexing_directive = 1;
-       yyextra->space_tokens = 0;
-       RETURN_TOKEN_NEVER_SKIP (IFNDEF);
+       if (!yyextra->in_define) {
+               BEGIN INITIAL;
+               yyextra->lexing_directive = 1;
+               yyextra->space_tokens = 0;
+               RETURN_TOKEN_NEVER_SKIP (IFNDEF);
+       }
 }
 
 <HASH>if/[^_a-zA-Z0-9] {
-       BEGIN INITIAL;
-       yyextra->lexing_directive = 1;
-       yyextra->space_tokens = 0;
-       RETURN_TOKEN_NEVER_SKIP (IF);
+       if (!yyextra->in_define) {
+               BEGIN INITIAL;
+               yyextra->lexing_directive = 1;
+               yyextra->space_tokens = 0;
+               RETURN_TOKEN_NEVER_SKIP (IF);
+       }
 }
 
 <HASH>elif/[^_a-zA-Z0-9] {
-       BEGIN INITIAL;
-       yyextra->lexing_directive = 1;
-       yyextra->space_tokens = 0;
-       RETURN_TOKEN_NEVER_SKIP (ELIF);
+       if (!yyextra->in_define) {
+               BEGIN INITIAL;
+               yyextra->lexing_directive = 1;
+               yyextra->space_tokens = 0;
+               RETURN_TOKEN_NEVER_SKIP (ELIF);
+       }
 }
 
 <HASH>else {
-       BEGIN INITIAL;
-       yyextra->space_tokens = 0;
-       RETURN_TOKEN_NEVER_SKIP (ELSE);
+       if (!yyextra->in_define) {
+               BEGIN INITIAL;
+               yyextra->space_tokens = 0;
+               RETURN_TOKEN_NEVER_SKIP (ELSE);
+       }
 }
 
 <HASH>endif {
-       BEGIN INITIAL;
-       yyextra->space_tokens = 0;
-       RETURN_TOKEN_NEVER_SKIP (ENDIF);
+       if (!yyextra->in_define) {
+               BEGIN INITIAL;
+               yyextra->space_tokens = 0;
+               RETURN_TOKEN_NEVER_SKIP (ENDIF);
+       }
 }
 
 <HASH>error[^\r\n]* {
@@ -399,7 +412,8 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
         *        and not whitespace). This will generate an error.
         */
 <HASH>define{HSPACE}* {
-       if (! parser->skipping) {
+       yyextra->in_define = true;
+       if (!parser->skipping) {
                BEGIN DEFINE;
                yyextra->space_tokens = 0;
                RETURN_TOKEN (DEFINE_TOKEN);
index c7e382ed30c7d34512eb8fbd76af8e31d3693216..e786b24b132a333db8ba6ecf9e66233fa845ff2c 100644 (file)
@@ -197,6 +197,7 @@ struct glcpp_parser {
        int first_non_space_token_this_line;
        int newline_as_space;
        int in_control_line;
+       bool in_define;
        int paren_count;
        int commented_newlines;
        skip_node_t *skip_stack;