https://gcc.gnu.org/g:1911b8cbd78293582b38d938350a7fa6b3c2d5eb
commit r15-7108-g1911b8cbd78293582b38d938350a7fa6b3c2d5eb Author: Jakub Jelinek <ja...@redhat.com> Date: Tue Jan 21 18:49:51 2025 +0100 c++: Handle CPP_EMBED in cp_parser_objc_message_args [PR118586] 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. 2025-01-21 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. Diff: --- gcc/cp/parser.cc | 20 +++++--- gcc/testsuite/obj-c++.dg/embed-1.mm | 15 ++++++ gcc/testsuite/obj-c++.dg/va-meth-2.mm | 87 +++++++++++++++++++++++++++++++++++ gcc/testsuite/objc.dg/embed-1.m | 14 ++++++ 4 files changed, 130 insertions(+), 6 deletions(-) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 37214dae5b11..398fd8538e2f 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -36734,14 +36734,22 @@ cp_parser_objc_message_args (cp_parser* 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); } diff --git a/gcc/testsuite/obj-c++.dg/embed-1.mm b/gcc/testsuite/obj-c++.dg/embed-1.mm new file mode 100644 index 000000000000..630a0f813918 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/embed-1.mm @@ -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]; +} diff --git a/gcc/testsuite/obj-c++.dg/va-meth-2.mm b/gcc/testsuite/obj-c++.dg/va-meth-2.mm new file mode 100644 index 000000000000..f5f096aef0b5 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/va-meth-2.mm @@ -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; +} diff --git a/gcc/testsuite/objc.dg/embed-1.m b/gcc/testsuite/objc.dg/embed-1.m new file mode 100644 index 000000000000..6e6877c104de --- /dev/null +++ b/gcc/testsuite/objc.dg/embed-1.m @@ -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]; +}