From 5f374908555f437ee5945a7d191d1cac6da3dfe2 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Tue, 24 Feb 2026 13:19:06 +1100 Subject: [PATCH] glcpp: fix paste within macro function expansion Note the tests added in 89cd6df03481 were wrong (confirmed in gcc) I've updated them to the expected outcome and enabled the paste test from 475222b0224c. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/13863 Fixes: d5cd40343f4a ("Expand macro arguments before performing argument substitution.") Reviewed-by: Eric R. Smith Part-of: --- src/compiler/glsl/glcpp/glcpp-parse.y | 25 ++++++++++++++++++- .../tests/114-paste-integer-tokens.c.expected | 8 +++--- .../150-token-accidental-concatenation.c | 2 +- ...-token-accidental-concatenation.c.expected | 2 +- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/compiler/glsl/glcpp/glcpp-parse.y b/src/compiler/glsl/glcpp/glcpp-parse.y index 8e1fb364dcc..67ff9359484 100644 --- a/src/compiler/glsl/glcpp/glcpp-parse.y +++ b/src/compiler/glsl/glcpp/glcpp-parse.y @@ -1930,6 +1930,7 @@ _glcpp_parser_expand_function(glcpp_parser_t *parser, token_node_t *node, /* Perform argument substitution on the replacement list. */ substituted = _token_list_create(parser); + bool prev_paste_token = false; for (node = macro->replacements->head; node; node = node->next) { if (node->token->type == IDENTIFIER && _string_list_contains(macro->parameters, node->token->value.str, @@ -1941,7 +1942,26 @@ _glcpp_parser_expand_function(glcpp_parser_t *parser, token_node_t *node, if (argument->head) { token_list_t *expanded_argument; expanded_argument = _token_list_copy(parser, argument); - _glcpp_parser_expand_token_list(parser, expanded_argument, mode); + + /* From the C99 spec Section 10.3.1 (Argument substitution): + * "After the arguments for the invocation of a function-like + * macro have been identified, argument substitution takes + * place. A parameter in the replacement list, unless preceded + * by a # or ## preprocessing token or followed by a ## + * preprocessing token (see below), is replaced by the + * corresponding argument after all macros contained therein + * have been expanded." + */ + + /* Look ahead for a PASTE token, skipping space. */ + token_node_t *next_non_space = node->next; + while (next_non_space && next_non_space->token->type == SPACE) + next_non_space = next_non_space->next; + + if (!prev_paste_token && + (!next_non_space || next_non_space->token->type != PASTE)) + _glcpp_parser_expand_token_list(parser, expanded_argument, mode); + _token_list_append_list(substituted, expanded_argument); } else { token_t *new_token; @@ -1953,6 +1973,9 @@ _glcpp_parser_expand_function(glcpp_parser_t *parser, token_node_t *node, } else { _token_list_append(parser, substituted, node->token); } + + if (node->token->type != SPACE) + prev_paste_token = node->token->type == PASTE; } /* Implement token pasting. */ diff --git a/src/compiler/glsl/glcpp/tests/114-paste-integer-tokens.c.expected b/src/compiler/glsl/glcpp/tests/114-paste-integer-tokens.c.expected index 5bc14befa67..45f2115491a 100644 --- a/src/compiler/glsl/glcpp/tests/114-paste-integer-tokens.c.expected +++ b/src/compiler/glsl/glcpp/tests/114-paste-integer-tokens.c.expected @@ -1,7 +1,7 @@ -4. HTTP code for Not Found: 404 -5. Hexadecimal for 20560: 5050 -6: Zip code for Nortonville, KS: 66060 -7. James Bond, as a number: 007 +4. HTTP code for Not Found: __LINE____FILE____LINE__ +5. Hexadecimal for 20560: __LINE____FILE____LINE____FILE__ +6: Zip code for Nortonville, KS: __LINE____LINE____FILE____LINE____FILE__ +7. James Bond, as a number: __FILE____FILE____LINE__ diff --git a/src/compiler/glsl/glcpp/tests/150-token-accidental-concatenation.c b/src/compiler/glsl/glcpp/tests/150-token-accidental-concatenation.c index 9e061b68a8c..ae85bebb2af 100644 --- a/src/compiler/glsl/glcpp/tests/150-token-accidental-concatenation.c +++ b/src/compiler/glsl/glcpp/tests/150-token-accidental-concatenation.c @@ -12,5 +12,5 @@ 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` +B(a, b) 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 index cdaf5949732..bb1a9326308 100644 --- a/src/compiler/glsl/glcpp/tests/150-token-accidental-concatenation.c.expected +++ b/src/compiler/glsl/glcpp/tests/150-token-accidental-concatenation.c.expected @@ -12,5 +12,5 @@ r s rs r s xa xb - +ab xa xb