From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 46167385782D for ; Fri, 16 Feb 2024 21:47:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 46167385782D Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 46167385782D Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708120075; cv=none; b=A9He7RQJdMynSTaD13u6kTGY5GRNtMpe3q5w/Y8wnWG9U3CbMF/jvpIXztXos9B4x32Zt/Wx15w2fc7ardRCq1bT9gdZ6jnzqeOL//KO3F2wZkpkMxekromQQ4oWPTkN9UOgwjowt0re3g5vn2cI120+lPN6M090kZgzRBmFG9E= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708120075; c=relaxed/simple; bh=rEp1RyJwTFncIotbYyofzBtgWZJcMnASQofhYA8mWhw=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=hWgKsDad/dh1A6B61wqhoTBjQKJp0fDx1QUpkzMan5z0OwOEZSbqdwbwGAErYFqLYPYUs27PUByQ4hulyM/VW5w9IR71R1xsWMfPYxRxpWG/VStCCYex8NzlCnOOlvhZp/qUJPsZfOOmZ6Ighxe45KmutFLR5OcjDuR7z+WjPoM= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1708120072; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references; bh=vmI3ziX8Hlf9piGdXa0vIgGesAu0FCuEe5I7xp6yC5U=; b=LN4HtiarDctOQ4LLaiDl2mcgJN9kNrlZFe1TygceFTgiJrGrb37rIdKK/0hhcAcQ3Kr2Oi R6kuav/Sh30rq2uS8nlMtTKBEMAFMqZC8EUx/IP7Fveto1/UyysaITakDBUNvk5qzo55cy T3j2+9lWQzQ0vYAl9ZhZH44hzQDNssQ= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-134-NaVPZrz-OQ-2JRjWzvDc0A-1; Fri, 16 Feb 2024 16:47:51 -0500 X-MC-Unique: NaVPZrz-OQ-2JRjWzvDc0A-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 54474811E79 for ; Fri, 16 Feb 2024 21:47:51 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.192.8]) by smtp.corp.redhat.com (Postfix) with ESMTPS id F0280AD76; Fri, 16 Feb 2024 21:47:50 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 41GLlmf8197594 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 16 Feb 2024 22:47:48 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 41GLllQW197593; Fri, 16 Feb 2024 22:47:47 +0100 Date: Fri, 16 Feb 2024 22:47:47 +0100 From: Jakub Jelinek To: Jason Merrill , gcc-patches@gcc.gnu.org Subject: Re: [PATCH] c++: Fix up parameter pack diagnostics on xobj vs. varargs functions [PR113802] Message-ID: Reply-To: Jakub Jelinek References: <76a12c05-670d-4c56-8d5a-60cdbba32f84@redhat.com> MIME-Version: 1.0 In-Reply-To: X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Fri, Feb 16, 2024 at 10:20:26PM +0100, Jakub Jelinek wrote: > I've tried that (see below), but am getting > Excess errors: > /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:33:29: error: parameter packs not expanded with '...': And the reason for those is that e.g. on the reduced struct S0 { void j(this auto... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } }; with the first posted patch we first do: if (xobj_param_p && (declarator && declarator->parameter_pack_p)) and clear declarator->parameter_pack_p there. Then comes if (parser->implicit_template_parms && ((token->type == CPP_ELLIPSIS && declarator_can_be_parameter_pack (declarator)) || (declarator && declarator->parameter_pack_p))) which is true only with the second patch and not the first. Adding if (parser->implicit_template_parms && ((token->type == CPP_ELLIPSIS && declarator_can_be_parameter_pack (declarator)) - || (declarator && declarator->parameter_pack_p))) + || (declarator && declarator->parameter_pack_p && !xobj_param_p))) { int latest_template_parm_idx = TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS (current_template_parms)); fixes some of the excess errors, but not all of them, e.g. on struct S1 { void h(this auto&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } }; it still remains. The problem in there is that apparently we need declarator->parameter_pack_p cleared on the xobj diagnostics iff it was previously set before the CPP_ELLIPSIS handling above it, but not if it was set in that handling. I'm afraid I have no idea why though. The following patch works. 2024-02-16 Jakub Jelinek PR c++/113802 * parser.cc (cp_parser_parameter_declaration): Move the xobj_param_p pack diagnostics after ellipsis handling, but only clear declarator->parameter_pack_p for it if it was set before CPP_ELLIPSIS handling. Ignore declarator->parameter_pack_p if xobj_param_p. 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-16 17:38:27.802845433 +0100 +++ gcc/cp/parser.cc 2024-02-16 22:42:38.393896067 +0100 @@ -25734,39 +25734,25 @@ cp_parser_parameter_declaration (cp_pars decl_specifiers.locations[ds_this] = 0; } - if (xobj_param_p - && ((declarator && declarator->parameter_pack_p) - || cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))) - { - 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"); - /* Suppress errors that occur down the line. */ - if (declarator) - declarator->parameter_pack_p = false; - } - /* If a function parameter pack was specified and an implicit template parameter was introduced during cp_parser_parameter_declaration, change any implicit parameters introduced into packs. */ if (parser->implicit_template_parms && ((token->type == CPP_ELLIPSIS && declarator_can_be_parameter_pack (declarator)) - || (declarator && declarator->parameter_pack_p))) + || (declarator && declarator->parameter_pack_p && !xobj_param_p))) { int latest_template_parm_idx = TREE_VEC_LENGTH (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); } + bool prev_parameter_pack_p = declarator && declarator->parameter_pack_p; if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) { tree type = decl_specifiers.type; @@ -25794,6 +25780,22 @@ cp_parser_parameter_declaration (cp_pars } } + if (xobj_param_p + && (declarator ? declarator->parameter_pack_p + : PACK_EXPANSION_P (decl_specifiers.type))) + { + 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"); + /* Suppress errors that occur down the line. */ + if (declarator) + declarator->parameter_pack_p = !prev_parameter_pack_p; + } + /* 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-02-15 20:01:40.349239387 +0100 +++ gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C 2024-02-16 21:57:48.269851483 +0100 @@ -24,7 +24,7 @@ void S::f12(this S s = {}) {} // { dg-er struct S0 { template - void f(this Selves...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void f(this Selves...) {} template 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 + void k(this Selves...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + template - void fd(this Selves...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void fd(this Selves...); template 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 + void kd(this Selves...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } }; struct S1 { template - void f(this Selves&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void f(this Selves&...) {} template 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 + void k(this Selves&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + template - void fd(this Selves&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void fd(this Selves&...); template 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 + void kd(this Selves&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } }; struct S2 { template - void f(this Selves&&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void f(this Selves&&...) {} template 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 + void k(this Selves&&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + template - void fd(this Selves&&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void fd(this Selves&&...); template 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 + void kd(this Selves&&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } }; struct S3 { template - void f(this Selves const&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void f(this Selves const&...) {} template 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 + void k(this Selves const&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + template - void fd(this Selves const&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void fd(this Selves const&...); template 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 + void kd(this Selves const&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } }; struct S4 { template - void f(this Selves const&&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void f(this Selves const&&...) {} template 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 + void k(this Selves const&&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + template - void fd(this Selves const&&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void fd(this Selves const&&...); template 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 + void kd(this Selves const&&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } +}; Jakub