glcpp: Avoid accidental token pasting in preprocessed result.
authorCarl Worth <cworth@cworth.org>
Tue, 20 Jul 2010 23:44:03 +0000 (16:44 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Wed, 21 Jul 2010 00:01:12 +0000 (17:01 -0700)
Consider this test case:

#define EMPTY
int foo = 1+EMPTY+4;

The expression should compile as the sequence of tokens 1, PLUS,
UNARY_POSITIVE, 4. But glcpp has been failing for this case since it
results in the string "1++4" which a compiler correctly sees as a
syntax error, (1, POST_INCREMENT, 4).

We fix this by changing any macro with an empty definition to result
in a single SPACE token rather than nothing. This then gives "1+ +4"
which compiles correctly.

This commit does touch up the two existing test cases which already
have empty macros, (to add the space to the expected result).

It also adds a new test case to exercise the above scenario.

src/glsl/glcpp/glcpp-parse.y
src/glsl/glcpp/tests/008-define-empty.c.expected
src/glsl/glcpp/tests/011-define-func-empty.c.expected
src/glsl/glcpp/tests/068-accidental-pasting.c [new file with mode: 0644]
src/glsl/glcpp/tests/068-accidental-pasting.c.expected [new file with mode: 0644]

index c37c9bcff0b1462f553917341a1cc1c57fbc68ca..e4dcc76e0a7f501ec5cb5d9609f351c000dfebb1 100644 (file)
@@ -1048,6 +1048,19 @@ _arguments_parse (argument_list_t *arguments,
        return FUNCTION_STATUS_SUCCESS;
 }
 
+static token_list_t *
+_token_list_create_with_one_space (void *ctx)
+{
+       token_list_t *list;
+       token_t *space;
+
+       list = _token_list_create (ctx);
+       space = _token_create_ival (list, SPACE, SPACE);
+       _token_list_append (list, space);
+
+       return list;
+}
+
 /* This is a helper function that's essentially part of the
  * implementation of _glcpp_parser_expand_node. It shouldn't be called
  * except for by that function.
@@ -1097,9 +1110,10 @@ _glcpp_parser_expand_function (glcpp_parser_t *parser,
                return NULL;
        }
 
+       /* Replace a macro defined as empty with a SPACE token. */
        if (macro->replacements == NULL) {
                talloc_free (arguments);
-               return _token_list_create (parser);
+               return _token_list_create_with_one_space (parser);
        }
 
        if (! ((_argument_list_length (arguments) == 
@@ -1203,7 +1217,7 @@ _glcpp_parser_expand_function (glcpp_parser_t *parser,
  *
  * Otherwise, returns the token list that results from the expansion
  * and sets *last to the last node in the list that was consumed by
- * the expansion. Specificallty, *last will be set as follows:
+ * the expansion. Specifically, *last will be set as follows:
  *
  *     As 'node' in the case of object-like macro expansion.
  *
@@ -1262,8 +1276,9 @@ _glcpp_parser_expand_node (glcpp_parser_t *parser,
        {
                *last = node;
 
+               /* Replace a macro defined as empty with a SPACE token. */
                if (macro->replacements == NULL)
-                       return _token_list_create (parser);
+                       return _token_list_create_with_one_space (parser);
 
                return _token_list_copy (parser, macro->replacements);
        }
index b28b04f643122b019e912540f228c8ed20be9eeb..c0f53d75c71fbc481332740027b011541669e036 100644 (file)
@@ -1,3 +1,3 @@
 
-
 
index b28b04f643122b019e912540f228c8ed20be9eeb..c0f53d75c71fbc481332740027b011541669e036 100644 (file)
@@ -1,3 +1,3 @@
 
-
 
diff --git a/src/glsl/glcpp/tests/068-accidental-pasting.c b/src/glsl/glcpp/tests/068-accidental-pasting.c
new file mode 100644 (file)
index 0000000..699ac51
--- /dev/null
@@ -0,0 +1,11 @@
+#define empty
+<empty<
+<empty=
+>empty>
+>empty=
+=empty=
+!empty=
+&empty&
+|empty|
++empty+
+-empty-
diff --git a/src/glsl/glcpp/tests/068-accidental-pasting.c.expected b/src/glsl/glcpp/tests/068-accidental-pasting.c.expected
new file mode 100644 (file)
index 0000000..ce41cd6
--- /dev/null
@@ -0,0 +1,12 @@
+
+< <
+< =
+> >
+> =
+= =
+! =
+& &
+| |
++ +
+- -
+