diff options
author | Carl Worth <cworth@cworth.org> | 2010-07-20 16:44:03 -0700 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2010-07-20 16:44:03 -0700 |
commit | a26648f9296989f4d2df05318c723f7ff58df1d7 (patch) | |
tree | df32357b5bf2c55b21e7ab28f67a816f7141475e | |
parent | 01c1ba7966e79e8eafffe3d5b62e6b8b50b481c6 (diff) |
glcpp: Avoid accidental token pasting in preprocessed result.
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.
-rw-r--r-- | src/glsl/glcpp/glcpp-parse.y | 21 | ||||
-rw-r--r-- | src/glsl/glcpp/tests/008-define-empty.c.expected | 2 | ||||
-rw-r--r-- | src/glsl/glcpp/tests/011-define-func-empty.c.expected | 2 | ||||
-rw-r--r-- | src/glsl/glcpp/tests/068-accidental-pasting.c | 11 | ||||
-rw-r--r-- | src/glsl/glcpp/tests/068-accidental-pasting.c.expected | 12 |
5 files changed, 43 insertions, 5 deletions
diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y index c37c9bcff0..e4dcc76e0a 100644 --- a/src/glsl/glcpp/glcpp-parse.y +++ b/src/glsl/glcpp/glcpp-parse.y @@ -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); } diff --git a/src/glsl/glcpp/tests/008-define-empty.c.expected b/src/glsl/glcpp/tests/008-define-empty.c.expected index b28b04f643..c0f53d75c7 100644 --- a/src/glsl/glcpp/tests/008-define-empty.c.expected +++ b/src/glsl/glcpp/tests/008-define-empty.c.expected @@ -1,3 +1,3 @@ - + diff --git a/src/glsl/glcpp/tests/011-define-func-empty.c.expected b/src/glsl/glcpp/tests/011-define-func-empty.c.expected index b28b04f643..c0f53d75c7 100644 --- a/src/glsl/glcpp/tests/011-define-func-empty.c.expected +++ b/src/glsl/glcpp/tests/011-define-func-empty.c.expected @@ -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 index 0000000000..699ac5144e --- /dev/null +++ b/src/glsl/glcpp/tests/068-accidental-pasting.c @@ -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 index 0000000000..ce41cd6e52 --- /dev/null +++ b/src/glsl/glcpp/tests/068-accidental-pasting.c.expected @@ -0,0 +1,12 @@ + +< < +< = +> > +> = += = +! = +& & +| | ++ + +- - + |