diff --git a/src/compiler/glsl/glcpp/glcpp-parse.y b/src/compiler/glsl/glcpp/glcpp-parse.y index 195588f512a..e6758a6ab98 100644 --- a/src/compiler/glsl/glcpp/glcpp-parse.y +++ b/src/compiler/glsl/glcpp/glcpp-parse.y @@ -1450,6 +1450,21 @@ _token_paste(glcpp_parser_t *parser, token_t *token, token_t *other) return token; } +/* + * Check to see if we need a space in between two tokens, for example to + * keep "+ +" from collapsing to "++" + */ +static bool +need_space_between(int token1, int token2) +{ + if ( (token1 == '+' || token1 == '-') && token2 == token1 ) + return true; + if (token1 == IDENTIFIER && + (token2 == IDENTIFIER || token2 == INTEGER)) + return true; + return false; +} + static void _token_list_print(glcpp_parser_t *parser, token_list_t *list) { @@ -1458,8 +1473,13 @@ _token_list_print(glcpp_parser_t *parser, token_list_t *list) if (list == NULL) return; - for (node = list->head; node; node = node->next) + for (node = list->head; node; node = node->next) { _token_print(parser->output, node->token); + /* avoid accidental token concatenation */ + if (node->next && + need_space_between(node->token->type, node->next->token->type)) + _mesa_string_buffer_append_char(parser->output, ' '); + } } void @@ -2030,21 +2050,6 @@ _glcpp_parser_expand_node(glcpp_parser_t *parser, token_node_t *node, replacement = _token_list_copy(parser, macro->replacements); - /* If needed insert space in front of replacements to isolate them from - * the code they will be inserted into. For example: - * - * #define VALUE -1.0 - * int a = -VALUE; - * - * Should be evaluated to int a = - -1.0; not int a = --1.0; - */ - if (node_prev && - (node_prev->token->type == '-' || node_prev->token->type == '+') && - node_prev->token->type == replacement->head->token->type) { - token_t *new_token = _token_create_ival(parser, SPACE, SPACE); - _token_list_prepend(parser, replacement, new_token); - } - _glcpp_parser_apply_pastes(parser, replacement); return replacement; } diff --git a/src/compiler/glsl/glcpp/tests/068-accidental-pasting.c b/src/compiler/glsl/glcpp/tests/068-accidental-pasting.c index 699ac5144e5..e1789fbba0a 100644 --- a/src/compiler/glsl/glcpp/tests/068-accidental-pasting.c +++ b/src/compiler/glsl/glcpp/tests/068-accidental-pasting.c @@ -1,3 +1,6 @@ +#define VALUE1 -1.0 +#define VALUE2 +2 +#define ONEPLUS(x) 1+x #define empty > @@ -9,3 +12,6 @@ | | + + - - +- -1.0 ++ +2 +1+ +1 diff --git a/src/compiler/glsl/glcpp/tests/150-token-accidental-concatenation.c b/src/compiler/glsl/glcpp/tests/150-token-accidental-concatenation.c new file mode 100644 index 00000000000..9e061b68a8c --- /dev/null +++ b/src/compiler/glsl/glcpp/tests/150-token-accidental-concatenation.c @@ -0,0 +1,16 @@ +/* + * avoid accidental concatenation of strings + * but make sure deliberate concatenation works + */ +#define a xa +#define b xb +#define A(x, y) x y +#define B(x, y) x ## y +#define C(x) x + +A(r, s) +B(r, s) +C(r)s +A(a, b) +//B(a, b) // not working yet; gcc and clang give `ab`, we give `xaxb` +C(a)b diff --git a/src/compiler/glsl/glcpp/tests/150-token-accidental-concatenation.c.expected b/src/compiler/glsl/glcpp/tests/150-token-accidental-concatenation.c.expected new file mode 100644 index 00000000000..cdaf5949732 --- /dev/null +++ b/src/compiler/glsl/glcpp/tests/150-token-accidental-concatenation.c.expected @@ -0,0 +1,16 @@ + + + + + + + + + + +r s +rs +r s +xa xb + +xa xb