From patchwork Fri Feb 16 09:03:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 85860 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 78D0B3858293 for ; Fri, 16 Feb 2024 09:04:03 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 169413858C54 for ; Fri, 16 Feb 2024 09:03:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 169413858C54 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 169413858C54 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708074211; cv=none; b=uGO7RECouJtcueZVXpVoXsEmbxTg+ckgmWK6vsPlX9Ai3QbAZQwFaMiulBe2YDooNCIZk8X5DrgrUlT5HLtEVxFx7QbpTREkfzG4z4W/vg67jSIrF4kDeCBDzlRjvShw1KM8bf8eHOdA0qvIWOrOUeoAxdci0gaM8ZU72tvhsKU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708074211; c=relaxed/simple; bh=BmCDxy52AI8JPF50UuOm8gzfwEBS9GXxdvgbMsNkkek=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=Iw5nVJ2boZJL57G8Rl9SQq7ARrWsRwi/J0jQbm8ZM0+jyxaQA6x+pmI1dUBjFx/i9mXKYYWQ3Eu/Q9gabpOCSD4dQtiNKppUEPIimZ7PXft4op20hrKNmL2FMkPHzGXg9Hxxx+iTlA2Ua0m3ghc+HKXe38nSoBTI9suiz3zS53w= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1708074200; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type; bh=yzqjFiCidVIzMfz25wCDVO1/LOx2yDayVNyYa9zpRMQ=; b=O/dB5v63IdzhWsxYIIAGJnOQ4UveX9nxxCgP/5PI/gbm++kTyxpMSP59lGf9PY9SVFEpwU j6vtp6Pja/85Y+ACbMLoIB+IS3vJDHoakGnX2JRmMwB5+J7WyLG7M6swTy7U7vEPZK/z+U Yd7CP3y3O9oWwKzq9DLX6MQ5QG+nNzU= 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-563-wibH2AecOXe-c4pU9exwSg-1; Fri, 16 Feb 2024 04:03:19 -0500 X-MC-Unique: wibH2AecOXe-c4pU9exwSg-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (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 C2E69828CE3 for ; Fri, 16 Feb 2024 09:03:18 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.192.8]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6B908C0335E; Fri, 16 Feb 2024 09:03:18 +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 41G93GM74070322 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 16 Feb 2024 10:03:16 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 41G93FLq4070321; Fri, 16 Feb 2024 10:03:15 +0100 Date: Fri, 16 Feb 2024 10:03:15 +0100 From: Jakub Jelinek To: Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] c++: Fix up parameter pack diagnostics on xobj vs. varargs functions [PR113802] Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.8 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com 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_H2, 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 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org 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 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. Jakub --- 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) + { + 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 - 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" } +};