Hi! As the following testcases show, I forgot to handle CPP_EMBED in cp_parser_objc_message_args which is another place which can parse possibly long valid lists of CPP_COMMA separated CPP_NUMBER tokens.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2025-01-20 Jakub Jelinek <ja...@redhat.com> PR objc++/118586 gcc/cp/ * parser.cc (cp_parser_objc_message_args): Handle CPP_EMBED. gcc/testsuite/ * objc.dg/embed-1.m: New test. * obj-c++.dg/embed-1.mm: New test. * obj-c++.dg/va-meth-2.mm: New test. --- gcc/cp/parser.cc.jj 2025-01-17 19:27:34.052140136 +0100 +++ gcc/cp/parser.cc 2025-01-20 20:16:23.082876036 +0100 @@ -36632,14 +36632,22 @@ cp_parser_objc_message_args (cp_parser* /* Handle non-selector arguments, if any. */ while (token->type == CPP_COMMA) { - tree arg; - cp_lexer_consume_token (parser->lexer); - arg = cp_parser_assignment_expression (parser); - addl_args - = chainon (addl_args, - build_tree_list (NULL_TREE, arg)); + if (cp_lexer_next_token_is (parser->lexer, CPP_EMBED)) + { + tree raw_data = cp_lexer_peek_token (parser->lexer)->u.value; + cp_lexer_consume_token (parser->lexer); + for (tree argument : raw_data_range (raw_data)) + addl_args = chainon (addl_args, + build_tree_list (NULL_TREE, argument)); + } + else + { + tree arg = cp_parser_assignment_expression (parser); + addl_args = chainon (addl_args, + build_tree_list (NULL_TREE, arg)); + } token = cp_lexer_peek_token (parser->lexer); } --- gcc/testsuite/objc.dg/embed-1.m.jj 2025-01-20 20:41:05.974260340 +0100 +++ gcc/testsuite/objc.dg/embed-1.m 2025-01-20 20:28:54.934427543 +0100 @@ -0,0 +1,14 @@ +/* PR objc++/118586 */ +/* { dg-do compile } */ + +@interface Foo ++ (int) bar: (int) firstNumber, int secondNumber, ...; +@end + +void +baz (void) +{ + [Foo bar: 1, 2, +#embed __FILE__ + , -1]; +} --- gcc/testsuite/obj-c++.dg/embed-1.mm.jj 2025-01-20 20:45:07.907894733 +0100 +++ gcc/testsuite/obj-c++.dg/embed-1.mm 2025-01-20 20:49:18.743405280 +0100 @@ -0,0 +1,15 @@ +// PR objc++/118586 +// { dg-do compile } +// { dg-options "" } + +@interface Foo ++ (int) bar: (int) firstNumber, int secondNumber, ...; +@end + +void +baz (void) +{ + [Foo bar: 1, 2, +#embed __FILE__ + , -1]; +} --- gcc/testsuite/obj-c++.dg/va-meth-2.mm.jj 2025-01-20 20:34:59.431358606 +0100 +++ gcc/testsuite/obj-c++.dg/va-meth-2.mm 2025-01-20 20:40:14.413977609 +0100 @@ -0,0 +1,87 @@ +/* PR objc++/118586 */ +/* Based on objc/execute/va_method.m, by Nicola Pero */ + +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ +#include "../objc-obj-c++-shared/TestsuiteObject.m" +#include <stdarg.h> +#include <stdlib.h> + +/* Test methods with "C-style" trailing arguments, with or without ellipsis. */ + +@interface MathClass: TestsuiteObject +/* sum positive numbers; -1 ends the list */ ++ (int) sum: (int) firstNumber, int secondNumber, ...; ++ (int) prod: (int) firstNumber, int secondNumber, int thirdNumber; ++ (int) minimum: (int) firstNumber, ...; +@end + +extern "C" int some_func(id self, SEL _cmd, int firstN, int secondN, int thirdN, ...) { + return firstN + secondN + thirdN; +} + +@implementation MathClass ++ (int) sum: (int) firstNumber, int secondNumber, ... +{ + va_list ap; + int sum = 0, number = 0; + + va_start (ap, secondNumber); + number = firstNumber + secondNumber; + + while (number >= 0) + { + sum += number; + number = va_arg (ap, int); + } + + va_end (ap); + + return sum; +} ++ (int) prod: (int) firstNumber, int secondNumber, int thirdNumber { + return firstNumber * secondNumber * thirdNumber; +} ++ (int) minimum: (int) firstNumber, ... +{ + va_list ap; + int minimum = 999, number = 0; + + va_start (ap, firstNumber); + number = firstNumber; + + while (number >= 0) + { + minimum = (minimum < number ? minimum: number); + number = va_arg (ap, int); + } + + va_end (ap); + + return minimum; +} +@end + +int main (void) +{ +#define ONETOTEN 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 + if ([MathClass sum: ONETOTEN, ONETOTEN, ONETOTEN, ONETOTEN, + ONETOTEN, ONETOTEN, ONETOTEN, ONETOTEN, ONETOTEN, ONETOTEN, + ONETOTEN, ONETOTEN, ONETOTEN, ONETOTEN, ONETOTEN, ONETOTEN, + ONETOTEN, ONETOTEN, ONETOTEN, ONETOTEN, ONETOTEN, ONETOTEN, + ONETOTEN, ONETOTEN, ONETOTEN, ONETOTEN, ONETOTEN, ONETOTEN, + ONETOTEN, ONETOTEN, -1] != 1650) + abort (); + if ([MathClass prod: 4, 5, 6] != 120) + abort (); +#define TWENTYONETOTHIRTY 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 + if ([MathClass minimum: TWENTYONETOTHIRTY, TWENTYONETOTHIRTY, + TWENTYONETOTHIRTY, TWENTYONETOTHIRTY, TWENTYONETOTHIRTY, + 17, 9, 133, 84, 35, TWENTYONETOTHIRTY, TWENTYONETOTHIRTY, + TWENTYONETOTHIRTY, TWENTYONETOTHIRTY, TWENTYONETOTHIRTY, + TWENTYONETOTHIRTY, TWENTYONETOTHIRTY, TWENTYONETOTHIRTY, + TWENTYONETOTHIRTY, TWENTYONETOTHIRTY, TWENTYONETOTHIRTY,-1] != 9) + abort (); + + return 0; +} Jakub