From patchwork Thu Oct 28 11:26:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 46735 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 9BCCF3858404 for ; Thu, 28 Oct 2021 11:27:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9BCCF3858404 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1635420438; bh=b2Gy8RFF1nGqI6e5X+QTnv5J+FofL3VcrbqbEnrTZu0=; h=Date:To:Subject:References:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=RKdgwdcqjz7efZJBcOkkrInPc934YPRYL0lGHBroEGWQO7DSrvElOZM5/qkf0a98D sX6iHY/5hoSFJy6GNNpkB/sRyucYC9PaFxSJyfy7XuXT8iR9gPCXqF9amiayPFS8fE olBMwrL2CGpFB6+sTRd2QwSATy9bw7DpABZw52e4= 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 [216.205.24.124]) by sourceware.org (Postfix) with ESMTPS id 191DC3857420 for ; Thu, 28 Oct 2021 11:26:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 191DC3857420 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-319-OBRzQ7llMOyGl-p4NN72EA-1; Thu, 28 Oct 2021 07:26:38 -0400 X-MC-Unique: OBRzQ7llMOyGl-p4NN72EA-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9321818125C0 for ; Thu, 28 Oct 2021 11:26:37 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.193.172]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 412525DF36; Thu, 28 Oct 2021 11:26:37 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.16.1/8.16.1) with ESMTPS id 19SBQYl22074038 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 28 Oct 2021 13:26:35 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.16.1/8.16.1/Submit) id 19SBQY8b2074037; Thu, 28 Oct 2021 13:26:34 +0200 Date: Thu, 28 Oct 2021 13:26:34 +0200 To: Jason Merrill Subject: [PATCH] c++, v2: Implement DR2351 - void{} [PR102820] Message-ID: <20211028112634.GO304296@tucnak> References: <20211021084240.GE304296@tucnak> MIME-Version: 1.0 In-Reply-To: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-5.4 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Cc: gcc-patches@gcc.gnu.org Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" On Wed, Oct 27, 2021 at 04:58:53PM -0400, Jason Merrill wrote: > On 10/21/21 04:42, Jakub Jelinek wrote: > > Hi! > > > > Here is an attempt to implement DR2351 - void{} - where void{} after > > pack expansion is considered valid and the same thing as void(). > > For templates, dunno if we have some better way to check if a CONSTRUCTOR > > might be empty after pack expansion. Would that only if the constructor > > only contains EXPR_PACK_EXPANSION elements and nothing else, or something > > else too? > > I think that's the only case. For template args there's the > pack_expansion_args_count function, but I don't think there's anything > similar for constructor elts; please feel free to add it. Ok. But counting how many packs its CONSTRUCTOR_ELTS have and then comparing that number against CONSTRUCTOR_NELTS seems to be unnecessarily expensive if there are many elements, for the purpose the DR2351 code needs we can stop as soon as we see first non-pack element. So what about this if it passes bootstrap/regtest? 2021-10-28 Jakub Jelinek PR c++/102820 * semantics.c (maybe_zero_constructor_nelts): New function. (finish_compound_literal): Implement DR2351 - void{}. If type is cv void and compound_literal has no elements, return void_node. If type is cv void and compound_literal might have no elements after expansion, handle it like other dependent compound literals. * g++.dg/cpp0x/dr2351.C: New test. Jakub --- gcc/cp/semantics.c.jj 2021-10-27 09:16:41.161600606 +0200 +++ gcc/cp/semantics.c 2021-10-28 13:06:59.325791588 +0200 @@ -3079,6 +3079,24 @@ finish_unary_op_expr (location_t op_loc, return result; } +/* Return true if CONSTRUCTOR EXPR after pack expansion could have no + elements. */ + +static bool +maybe_zero_constructor_nelts (tree expr) +{ + if (CONSTRUCTOR_NELTS (expr) == 0) + return true; + if (!processing_template_decl) + return false; + unsigned int i; + tree val; + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), i, val) + if (!PACK_EXPANSION_P (val)) + return false; + return true; +} + /* Finish a compound-literal expression or C++11 functional cast with aggregate initializer. TYPE is the type to which the CONSTRUCTOR in COMPOUND_LITERAL is being cast. */ @@ -3104,9 +3122,20 @@ finish_compound_literal (tree type, tree if (!TYPE_OBJ_P (type)) { - if (complain & tf_error) - error ("compound literal of non-object type %qT", type); - return error_mark_node; + /* DR2351 */ + if (VOID_TYPE_P (type) && CONSTRUCTOR_NELTS (compound_literal) == 0) + return void_node; + else if (VOID_TYPE_P (type) + && processing_template_decl + && maybe_zero_constructor_nelts (compound_literal)) + /* If there are only packs in compound_literal, it could + be void{} after pack expansion. */; + else + { + if (complain & tf_error) + error ("compound literal of non-object type %qT", type); + return error_mark_node; + } } if (template_placeholder_p (type)) --- gcc/testsuite/g++.dg/cpp0x/dr2351.C.jj 2021-10-28 12:59:27.987120315 +0200 +++ gcc/testsuite/g++.dg/cpp0x/dr2351.C 2021-10-28 13:15:20.532760871 +0200 @@ -0,0 +1,51 @@ +// DR2351 +// { dg-do compile { target c++11 } } + +void +foo () +{ + void{}; + void(); +} + +template +void +bar (T... t) +{ + void{t...}; + void(t...); +} + +void +baz () +{ + bar (); +} + +template +void +qux (T... t) +{ + void{t...}; // { dg-error "compound literal of non-object type" } +} + +void +corge () +{ + qux (1, 2); +} + +template +void +garply (T... t) +{ + void{t..., t..., t...}; + void(t..., t..., t...); +} + +template +void +grault (T... t) +{ + void{t..., 1}; // { dg-error "compound literal of non-object type" } +}