diff --git a/.pick_status.json b/.pick_status.json index f28b9fbf360..63f5ce3c9cb 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -3094,7 +3094,7 @@ "description": "glcpp: fix paste within macro function expansion", "nominated": true, "nomination_type": 2, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "d5cd40343f4a83d3270cb87ef38e85dcb9682e8c", "notes": null diff --git a/src/compiler/glsl/glcpp/glcpp-parse.y b/src/compiler/glsl/glcpp/glcpp-parse.y index e6758a6ab98..459856ddef1 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; } /* After argument substitution, and before further expansion 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