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.
This commit is contained in:
@@ -1048,6 +1048,19 @@ _arguments_parse (argument_list_t *arguments,
|
|||||||
return FUNCTION_STATUS_SUCCESS;
|
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
|
/* This is a helper function that's essentially part of the
|
||||||
* implementation of _glcpp_parser_expand_node. It shouldn't be called
|
* implementation of _glcpp_parser_expand_node. It shouldn't be called
|
||||||
* except for by that function.
|
* except for by that function.
|
||||||
@@ -1097,9 +1110,10 @@ _glcpp_parser_expand_function (glcpp_parser_t *parser,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Replace a macro defined as empty with a SPACE token. */
|
||||||
if (macro->replacements == NULL) {
|
if (macro->replacements == NULL) {
|
||||||
talloc_free (arguments);
|
talloc_free (arguments);
|
||||||
return _token_list_create (parser);
|
return _token_list_create_with_one_space (parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! ((_argument_list_length (arguments) ==
|
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
|
* Otherwise, returns the token list that results from the expansion
|
||||||
* and sets *last to the last node in the list that was consumed by
|
* 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.
|
* As 'node' in the case of object-like macro expansion.
|
||||||
*
|
*
|
||||||
@@ -1262,8 +1276,9 @@ _glcpp_parser_expand_node (glcpp_parser_t *parser,
|
|||||||
{
|
{
|
||||||
*last = node;
|
*last = node;
|
||||||
|
|
||||||
|
/* Replace a macro defined as empty with a SPACE token. */
|
||||||
if (macro->replacements == NULL)
|
if (macro->replacements == NULL)
|
||||||
return _token_list_create (parser);
|
return _token_list_create_with_one_space (parser);
|
||||||
|
|
||||||
return _token_list_copy (parser, macro->replacements);
|
return _token_list_copy (parser, macro->replacements);
|
||||||
}
|
}
|
||||||
|
11
src/glsl/glcpp/tests/068-accidental-pasting.c
Normal file
11
src/glsl/glcpp/tests/068-accidental-pasting.c
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#define empty
|
||||||
|
<empty<
|
||||||
|
<empty=
|
||||||
|
>empty>
|
||||||
|
>empty=
|
||||||
|
=empty=
|
||||||
|
!empty=
|
||||||
|
&empty&
|
||||||
|
|empty|
|
||||||
|
+empty+
|
||||||
|
-empty-
|
12
src/glsl/glcpp/tests/068-accidental-pasting.c.expected
Normal file
12
src/glsl/glcpp/tests/068-accidental-pasting.c.expected
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
< <
|
||||||
|
< =
|
||||||
|
> >
|
||||||
|
> =
|
||||||
|
= =
|
||||||
|
! =
|
||||||
|
& &
|
||||||
|
| |
|
||||||
|
+ +
|
||||||
|
- -
|
||||||
|
|
Reference in New Issue
Block a user