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 ESMTP id B5CC03955431 for ; Mon, 16 Aug 2021 19:18:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B5CC03955431 Received: from mail-qv1-f72.google.com (mail-qv1-f72.google.com [209.85.219.72]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-596-3lk8w3s4Mr6gumhl13wK4g-1; Mon, 16 Aug 2021 15:18:37 -0400 X-MC-Unique: 3lk8w3s4Mr6gumhl13wK4g-1 Received: by mail-qv1-f72.google.com with SMTP id bc19-20020ad45693000000b0035ccbd692a2so5018084qvb.13 for ; Mon, 16 Aug 2021 12:18:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=ejXRTf09MrmJrZoY/X5MaK7o+E7hEnFt1xfiDXm9sBg=; b=RaFIZCGdF491KPdeB2gU0IBOjLMT9QueyRGUkCXnoDABcdP5On5nMF68yEYYLraby1 uvmTce7W4wpt06gQk8F+ISHjef6WJydqrkMp0jDDsjK52i8f8JOqsdVrSbrNJeSPAe+3 5FcGhaTHO1IfXyq1aLt7W618SdVQRsnM29q7sbjzn5yw/c5p+/mJH5CZTXPTm4mhqss7 7Li33k3O1XGWU9tIYf6mchZm4Y22/JVv7ZWEYUat6NzPom31VTwNIaCXTolNCKmQZ+/j M9O6QLws/fMtOPkOo3ecdKsWkeBrhWnQpeAK5BLtPYQWr5hAhUwOMBrypajHmmi8LJod 6f/w== X-Gm-Message-State: AOAM531/krb6Bck+6qhCmtLiVa8Q9WQ0lPTZmuL8sZW3jMZJL3qlwxJG wS1qS9JEcImZoXYesdIPX5RLu0xKb3nT4bp+EIum8rVGsaLl/D1ZrxpKIIS3PWCD9R9qASjkuKI Y82uqx9ghmhAQeghBWA== X-Received: by 2002:aed:3022:: with SMTP id 31mr413009qte.343.1629141517172; Mon, 16 Aug 2021 12:18:37 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyP9OkfqgWpQ6irhRobg3RVJOVp+xLgWqzGWNrsYkgZU3hpMw3Cy1gK9nleG1VG4sSFw5HHBg== X-Received: by 2002:aed:3022:: with SMTP id 31mr412996qte.343.1629141516983; Mon, 16 Aug 2021 12:18:36 -0700 (PDT) Received: from redhat.com ([2601:184:4780:4310::b5dd]) by smtp.gmail.com with ESMTPSA id a5sm94393qta.49.2021.08.16.12.18.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 12:18:36 -0700 (PDT) Date: Mon, 16 Aug 2021 15:18:34 -0400 From: Marek Polacek To: Patrick Palka Cc: gcc-patches@gcc.gnu.org Subject: Re: [PATCH] c++: aggregate CTAD and brace elision [PR101344] Message-ID: References: <20210816190608.1339856-1-ppalka@redhat.com> MIME-Version: 1.0 In-Reply-To: <20210816190608.1339856-1-ppalka@redhat.com> User-Agent: Mutt/2.0.7 (2021-05-04) 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=-13.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, 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-List-Received-Date: Mon, 16 Aug 2021 19:18:41 -0000 On Mon, Aug 16, 2021 at 03:06:08PM -0400, Patrick Palka via Gcc-patches wrote: > During aggregate CTAD, collect_ctor_idx_types always recurses into a > sub-CONSTRUCTOR, regardless of whether the corresponding pair of braces > was elided in the original initializer. This causes us to reject some > completely-braced forms of aggregate CTAD as in the first testcase > below, because collect_ctor_idx_types effectively assumes that the given > initializer is always minimally-braced (hence the aggregate deduction > candidate is given a function type that's incompatible with the written > initializer). > > This patch fixes this by making reshape_init flag CONSTRUCTORs that > were built to undo brace elision in the original CONSTRUCTOR, so that > collect_ctor_idx_types can determine whether to recurse into a > sub-CONSTRUCTOR by simply inspecting this flag. > > This happens to also fix PR101820, which is about aggregate CTAD using > designated initializers, for a similar reason as above. > > A tricky case is the "intermediately-braced" initialization of 'e3' > in the first testcase below. It seems to me we're correct to continue > to reject this according to [over.match.class.deduct]/1 because here > the initializer element {1, 2, 3, 4} corresponds to the subobject E::t, > hence the type T_1 of the first funciton parameter of the aggregate > deduction candidate is T(&&)[2][2] which the argument {1, 2, 3, 4} isn't > compatible with (as opposed to say T(&&)[4]). > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > trunk/11? > > PR c++/101344 > PR c++/101820 > > gcc/cp/ChangeLog: > > * cp-tree.h (CONSTRUCTOR_BRACES_ELIDED_P): Define. > * decl.c (reshape_init_r): Set it. > * pt.c (collect_ctor_idx_types): Recurse into a sub-CONSTRUCTOR > iff CONSTRUCTOR_BRACES_ELIDED_P. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/class-deduction-aggr11.C: New test. > * g++.dg/cpp2a/class-deduction-aggr12.C: New test. > --- > gcc/cp/cp-tree.h | 6 ++++ > gcc/cp/decl.c | 18 +++++++++--- > gcc/cp/pt.c | 7 +---- > .../g++.dg/cpp2a/class-deduction-aggr11.C | 29 +++++++++++++++++++ > .../g++.dg/cpp2a/class-deduction-aggr12.C | 15 ++++++++++ > 5 files changed, 65 insertions(+), 10 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr11.C > create mode 100644 gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr12.C > > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > index bd3f12a393e..8cbf6cc30b0 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -4502,6 +4502,12 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) > #define CONSTRUCTOR_IS_PAREN_INIT(NODE) \ > (CONSTRUCTOR_CHECK(NODE)->base.private_flag) > > +/* True if reshape_init built this CONSTRUCTOR to undo the brace elision > + of another CONSTRUCTOR. This flag is used during C++20 aggregate > + CTAD. */ > +#define CONSTRUCTOR_BRACES_ELIDED_P(NODE) \ > + (CONSTRUCTOR_CHECK (NODE)->base.protected_flag) > + > /* True if NODE represents a conversion for direct-initialization in a > template. Set by perform_implicit_conversion_flags. */ > #define IMPLICIT_CONV_EXPR_DIRECT_INIT(NODE) \ > diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c > index b3671ee8956..9e257b32e18 100644 > --- a/gcc/cp/decl.c > +++ b/gcc/cp/decl.c > @@ -6650,7 +6650,8 @@ reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p, > /* A non-aggregate type is always initialized with a single > initializer. */ > if (!CP_AGGREGATE_TYPE_P (type) > - /* As is an array with dependent bound. */ > + /* As is an array with dependent bound, which we can see > + during C++20 aggregate CTAD. */ > || (cxx_dialect >= cxx20 > && TREE_CODE (type) == ARRAY_TYPE > && uses_template_parms (TYPE_DOMAIN (type)))) > @@ -6767,6 +6768,7 @@ reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p, > initializer already, and there is not a CONSTRUCTOR, it means that there > is a missing set of braces (that is, we are processing the case for > which reshape_init exists). */ > + bool braces_elided_p = false; > if (!first_initializer_p) > { > if (TREE_CODE (stripped_init) == CONSTRUCTOR) > @@ -6802,17 +6804,25 @@ reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p, > warning (OPT_Wmissing_braces, > "missing braces around initializer for %qT", > type); > + braces_elided_p = true; > } > > /* Dispatch to specialized routines. */ > + tree new_init; > if (CLASS_TYPE_P (type)) > - return reshape_init_class (type, d, first_initializer_p, complain); > + new_init = reshape_init_class (type, d, first_initializer_p, complain); > else if (TREE_CODE (type) == ARRAY_TYPE) > - return reshape_init_array (type, d, first_initializer_p, complain); > + new_init = reshape_init_array (type, d, first_initializer_p, complain); > else if (VECTOR_TYPE_P (type)) > - return reshape_init_vector (type, d, complain); > + new_init = reshape_init_vector (type, d, complain); > else > gcc_unreachable(); > + > + if (braces_elided_p) > + if (TREE_CODE (new_init) == CONSTRUCTOR) > + CONSTRUCTOR_BRACES_ELIDED_P (new_init) = 1; Any reason for the two ifs and not an &&? Marek