From: Jason Merrill <jason@redhat.com>
To: Jakub Jelinek <jakub@redhat.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] c++: Fix up parameter pack diagnostics on xobj vs. varargs functions [PR113802]
Date: Fri, 16 Feb 2024 15:47:41 -0500 [thread overview]
Message-ID: <76a12c05-670d-4c56-8d5a-60cdbba32f84@redhat.com> (raw)
In-Reply-To: <Zc8k0y5zsJQhZ+2k@tucnak>
On 2/16/24 04:03, Jakub Jelinek wrote:
> Hi!
>
> The simple presence of ellipsis as next token after the parameter
> declaration doesn't imply it is a parameter pack, it sometimes is, e.g.
> if its type is a pack, but sometimes is not and in that case it acts
> the same as if the next tokens were , ... instead of just ...
> The xobj param cannot be a function parameter pack though treats both
> the declarator->parameter_pack_p and token->type == CPP_ELLIPSIS as
> sufficient conditions for the error. The conditions for CPP_ELLIPSIS
> are done a little bit later in the same function and complex enough that
> IMHO shouldn't be repeated, on the other side for the
> declarator->parameter_pack_p case we clear that flag for xobj params
> for error recovery reasons.
> In order to avoid diagnosing this in two spots, one at the current spot
> for declarator->parameter_pack_p and one for the ellipsis case after
> we decide if it is parameter pack or varargs, the following patch instead
> just sets a boolean flag whether we should emit this diagnostics, does it
> early for declarator->parameter_pack_p case and clears the parameter_pack_p
> flag in that case like the older patch did, and for the ellipsis case
> sets the flag later, then emits the diagnostics.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2024-02-16 Jakub Jelinek <jakub@redhat.com>
>
> PR c++/113802
> * parser.cc (cp_parser_parameter_declaration): Don't emit
> PR113307 diagnostics too early, instead for the
> declarator->parameter_pack_p case just set a flag it should be emitted
> later. Set that flag also when consuming following ellipsis as part
> of a parameter pack and diagnose either afterwards. Formatting fix.
>
> * g++.dg/cpp23/explicit-obj-diagnostics3.C (S0, S1, S2, S3, S4): Don't
> expect any diagnostics on f and fd member function templates, add
> similar templates with ...Selves instead of Selves as k and kd and
> expect diagnostics for those.
>
> --- gcc/cp/parser.cc.jj 2024-02-14 14:26:19.000000000 +0100
> +++ gcc/cp/parser.cc 2024-02-15 11:58:27.033618967 +0100
> @@ -25727,17 +25727,10 @@ cp_parser_parameter_declaration (cp_pars
> bool const xobj_param_p
> = decl_spec_seq_has_spec_p (&decl_specifiers, ds_this);
>
> - if (xobj_param_p
> - && ((declarator && declarator->parameter_pack_p)
> - || cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)))
> + bool diag_xobj_parameter_pack = false;
> + if (xobj_param_p && (declarator && declarator->parameter_pack_p))
> {
> - location_t xobj_param
> - = make_location (decl_specifiers.locations[ds_this],
> - decl_spec_token_start->location,
> - input_location);
> - error_at (xobj_param,
> - "an explicit object parameter cannot "
> - "be a function parameter pack");
> + diag_xobj_parameter_pack = true;
> /* Suppress errors that occur down the line. */
> if (declarator)
> declarator->parameter_pack_p = false;
> @@ -25755,9 +25748,10 @@ cp_parser_parameter_declaration (cp_pars
> (INNERMOST_TEMPLATE_PARMS (current_template_parms));
>
> if (latest_template_parm_idx != template_parm_idx)
> - decl_specifiers.type = convert_generic_types_to_packs
> - (decl_specifiers.type,
> - template_parm_idx, latest_template_parm_idx);
> + decl_specifiers.type
> + = convert_generic_types_to_packs (decl_specifiers.type,
> + template_parm_idx,
> + latest_template_parm_idx);
> }
>
> if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
> @@ -25773,6 +25767,8 @@ cp_parser_parameter_declaration (cp_pars
> || (!type && template_parm_p))
> && declarator_can_be_parameter_pack (declarator))
> {
> + if (xobj_param_p)
> + diag_xobj_parameter_pack = true;
> /* Consume the `...'. */
> cp_lexer_consume_token (parser->lexer);
> maybe_warn_variadic_templates ();
> @@ -25787,6 +25783,17 @@ cp_parser_parameter_declaration (cp_pars
> }
> }
>
> + if (diag_xobj_parameter_pack)
Can we move all the xobj handling down here (where we can trust
declarator->parameter_pack_p) instead of adding a new variable?
> + {
> + location_t xobj_param
> + = make_location (decl_specifiers.locations[ds_this],
> + decl_spec_token_start->location,
> + input_location);
> + error_at (xobj_param,
> + "an explicit object parameter cannot "
> + "be a function parameter pack");
> + }
> +
> /* The restriction on defining new types applies only to the type
> of the parameter, not to the default argument. */
> parser->type_definition_forbidden_message = saved_message;
> --- gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C.jj 2024-01-17 10:34:49.812597960 +0100
> +++ gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C 2024-02-15 12:14:29.994356800 +0100
> @@ -24,7 +24,7 @@ void S::f12(this S s = {}) {} // { dg-er
>
> struct S0 {
> template<typename Selves>
> - void f(this Selves...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> + void f(this Selves...) {}
>
> template<typename Selves>
> void g(this Selves... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> @@ -32,19 +32,25 @@ struct S0 {
> void h(this auto...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> void j(this auto... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
>
> + template<typename ...Selves>
> + void k(this Selves...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> +
> template<typename Selves>
> - void fd(this Selves...); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> + void fd(this Selves...);
>
> template<typename Selves>
> void gd(this Selves... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
>
> void hd(this auto...); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> void jd(this auto... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> +
> + template<typename ...Selves>
> + void kd(this Selves...); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> };
>
> struct S1 {
> template<typename Selves>
> - void f(this Selves&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> + void f(this Selves&...) {}
>
> template<typename Selves>
> void g(this Selves&... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> @@ -52,19 +58,25 @@ struct S1 {
> void h(this auto&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> void j(this auto&... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
>
> + template<typename ...Selves>
> + void k(this Selves&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> +
> template<typename Selves>
> - void fd(this Selves&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> + void fd(this Selves&...);
>
> template<typename Selves>
> void gd(this Selves&... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
>
> void hd(this auto&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> void jd(this auto&... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> +
> + template<typename ...Selves>
> + void kd(this Selves&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> };
>
> struct S2 {
> template<typename Selves>
> - void f(this Selves&&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> + void f(this Selves&&...) {}
>
> template<typename Selves>
> void g(this Selves&&... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> @@ -72,19 +84,25 @@ struct S2 {
> void h(this auto&&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> void j(this auto&&... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
>
> + template<typename ...Selves>
> + void k(this Selves&&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> +
> template<typename Selves>
> - void fd(this Selves&&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> + void fd(this Selves&&...);
>
> template<typename Selves>
> void gd(this Selves&&... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
>
> void hd(this auto&&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> void jd(this auto&&... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> +
> + template<typename ...Selves>
> + void kd(this Selves&&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> };
>
> struct S3 {
> template<typename Selves>
> - void f(this Selves const&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> + void f(this Selves const&...) {}
>
> template<typename Selves>
> void g(this Selves const&... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> @@ -92,19 +110,25 @@ struct S3 {
> void h(this auto const&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> void j(this auto const&... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
>
> + template<typename ...Selves>
> + void k(this Selves const&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> +
> template<typename Selves>
> - void fd(this Selves const&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> + void fd(this Selves const&...);
>
> template<typename Selves>
> void gd(this Selves const&... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
>
> void hd(this auto const&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> void jd(this auto const&... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> +
> + template<typename ...Selves>
> + void kd(this Selves const&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> };
>
> struct S4 {
> template<typename Selves>
> - void f(this Selves const&&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> + void f(this Selves const&&...) {}
>
> template<typename Selves>
> void g(this Selves const&&... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> @@ -112,13 +136,18 @@ struct S4 {
> void h(this auto const&&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> void j(this auto const&&... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
>
> + template<typename ...Selves>
> + void k(this Selves const&&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> +
> template<typename Selves>
> - void fd(this Selves const&&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> + void fd(this Selves const&&...);
>
> template<typename Selves>
> void gd(this Selves const&&... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
>
> void hd(this auto const&&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> void jd(this auto const&&... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> -};
>
> + template<typename ...Selves>
> + void kd(this Selves const&&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> +};
>
> Jakub
>
next prev parent reply other threads:[~2024-02-16 20:47 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-16 9:03 Jakub Jelinek
2024-02-16 20:47 ` Jason Merrill [this message]
2024-02-16 21:20 ` Jakub Jelinek
2024-02-16 21:47 ` Jakub Jelinek
2024-02-16 22:15 ` Jakub Jelinek
2024-03-06 23:43 ` Jason Merrill
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=76a12c05-670d-4c56-8d5a-60cdbba32f84@redhat.com \
--to=jason@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jakub@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).