From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-1.mimecast.com (us-smtp-2.mimecast.com [205.139.110.61]) by sourceware.org (Postfix) with ESMTP id CFF50384A40A for ; Wed, 2 Sep 2020 16:00:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org CFF50384A40A Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-268-E7PFUouFMVKdFZsRZdFf7A-1; Wed, 02 Sep 2020 12:00:33 -0400 X-MC-Unique: E7PFUouFMVKdFZsRZdFf7A-1 Received: by mail-qt1-f198.google.com with SMTP id f5so88499qtk.11 for ; Wed, 02 Sep 2020 09:00:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=0yHswIkcGYr5MLrmUP2NCU4wZKxJbnmlaI2RZxSmUYU=; b=XxdENqNseUAx5zT/9TqdN1utOPy7jlUZW9Ct6WhD9YXymE8A0v0rZN5vb7G2dflfR7 AtHeUwkl43RptoJt02/rNaXZ6EumherORxp9XWHYsHKwMI84qQpTA1HNxsKwQl3mivGD EG23r6HHsk3x5q/xXH16OGRhUhFDQ1SGBYRXMdIAxRawyQs8TcbR19FqN6G07ukWNkP/ SIsEPJ+Koqq+Wo3KQOw1d0WosX2/plno/lQPWgsZwXCcAr5CgCZ77zerEadhNHNFGFzc q9Eqo00ZcbGgfKx/qZLDCWYJxOiBro+ozRcMs/zgn9yRfHKzEEjwt70xl5HK3cj4Jfwt 3Kng== X-Gm-Message-State: AOAM5304ICAU5o+mKbl/jX/dlc59/J99whiqMBSvmT6GD7dRG0MQFY7+ jH+FgKaXQ0hVQTCxbbaJdiBCt8hKVN5CuSbkv3c11a7Nh8CTCFYAl1q0wPFtMq6/Il2NAfpPSsH KpeOHp1V2psZf6IeAYQ== X-Received: by 2002:a37:d53:: with SMTP id 80mr7306828qkn.136.1599062431783; Wed, 02 Sep 2020 09:00:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwetN7tC9EAqK0SeUVYbY++44rP/PMmGKozMkkbM7HJAPPyRZLwUa1XL22FcmDEgoboVi7GjQ== X-Received: by 2002:a37:d53:: with SMTP id 80mr7306789qkn.136.1599062431306; Wed, 02 Sep 2020 09:00:31 -0700 (PDT) Received: from [192.168.1.148] (209-6-216-142.s141.c3-0.smr-cbr1.sbo-smr.ma.cable.rcncustomer.com. [209.6.216.142]) by smtp.gmail.com with ESMTPSA id e13sm4807453qtr.85.2020.09.02.09.00.30 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 02 Sep 2020 09:00:30 -0700 (PDT) Subject: Re: [PATCH] c++: Fix P0960 in member init list and array [PR92812] To: Marek Polacek , GCC Patches References: <20200901222354.234729-1-polacek@redhat.com> From: Jason Merrill Message-ID: <76109e86-fce4-00d4-8fba-f8f57df36da5@redhat.com> Date: Wed, 2 Sep 2020 12:00:29 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.6.0 MIME-Version: 1.0 In-Reply-To: <20200901222354.234729-1-polacek@redhat.com> X-Mimecast-Spam-Score: 0.002 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-Language: en-US X-Spam-Status: No, score=-16.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: Wed, 02 Sep 2020 16:00:37 -0000 On 9/1/20 6:23 PM, Marek Polacek wrote: > This patch nails down the remaining P0960 case in PR92812: > > struct A { > int ar[2]; > A(): ar(1, 2) {} // doesn't work without this patch > }; > > Note that when the target object is not of array type, this already > works: > > struct S { int x, y; }; > struct A { > S s; > A(): s(1, 2) { } // OK in C++20 > }; > > because build_new_method_call_1 takes care of the P0960 magic. > > It proved to be quite hairy. When the ()-list has more than one > element, we can always create a CONSTRUCTOR, because the code was > previously invalid. But when the ()-list has just one element, it > gets all kinds of difficult. As usual, we have to handle a("foo") > so as not to wrap the STRING_CST in a CONSTRUCTOR. Always turning > x(e) into x{e} would run into trouble as in c++/93790. Another > issue was what to do about x({e}): previously, this would trigger > "list-initializer for non-class type must not be parenthesized". > I figured I'd make this work in C++20, so that given > > struct S { int x, y; }; > > you can do > > S a[2]; > [...] > A(): a({1, 2}) // initialize a[0] with {1, 2} and a[1] with {} > > It also turned out that, as an extension, we support compound literals: > > F (): m((S[1]) { 1, 2 }) > > so this has to keep working as before. > > Moreover, make sure not to trigger in compiler-generated code, like > =default, where array assignment is allowed. > > paren-init35.C also tests this with vector types. > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? > > gcc/cp/ChangeLog: > > PR c++/92812 > * init.c (do_paren_init_for_array_p): New. > (perform_member_init): Use it. If true, build up a CONSTRUCTOR > from the list of arguments. > > gcc/testsuite/ChangeLog: > > PR c++/92812 > * g++.dg/cpp0x/constexpr-array23.C: Adjust dg-error. > * g++.dg/cpp0x/initlist69.C: Likewise. > * g++.dg/diagnostic/mem-init1.C: Likewise. > * g++.dg/init/array28.C: Likewise. > * g++.dg/cpp2a/paren-init33.C: New test. > * g++.dg/cpp2a/paren-init34.C: New test. > * g++.dg/cpp2a/paren-init35.C: New test. > * g++.old-deja/g++.brendan/crash60.C: Adjust dg-error. > * g++.old-deja/g++.law/init10.C: Likewise. > * g++.old-deja/g++.other/array3.C: Likewise. > --- > gcc/cp/init.c | 64 ++++++++- > .../g++.dg/cpp0x/constexpr-array23.C | 6 +- > gcc/testsuite/g++.dg/cpp0x/initlist69.C | 4 +- > gcc/testsuite/g++.dg/cpp2a/paren-init33.C | 128 ++++++++++++++++++ > gcc/testsuite/g++.dg/cpp2a/paren-init34.C | 25 ++++ > gcc/testsuite/g++.dg/cpp2a/paren-init35.C | 21 +++ > gcc/testsuite/g++.dg/diagnostic/mem-init1.C | 4 +- > gcc/testsuite/g++.dg/init/array28.C | 2 +- > .../g++.old-deja/g++.brendan/crash60.C | 2 +- > gcc/testsuite/g++.old-deja/g++.law/init10.C | 2 +- > gcc/testsuite/g++.old-deja/g++.other/array3.C | 3 +- > 11 files changed, 243 insertions(+), 18 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/paren-init33.C > create mode 100644 gcc/testsuite/g++.dg/cpp2a/paren-init34.C > create mode 100644 gcc/testsuite/g++.dg/cpp2a/paren-init35.C > > diff --git a/gcc/cp/init.c b/gcc/cp/init.c > index d4540db3605..2edc9651ad6 100644 > --- a/gcc/cp/init.c > +++ b/gcc/cp/init.c > @@ -756,6 +756,41 @@ maybe_warn_list_ctor (tree member, tree init) > "of the underlying array", member, begin); > } > > +/* Return true if we should attempt to perform the P0960 magic when > + initializing an array TYPE from a parenthesized list of values LIST. */ > + > +static bool > +do_paren_init_for_array_p (tree list, tree type) > +{ > + if (cxx_dialect < cxx20) > + /* P0960 is a C++20 feature. */ > + return false; > + > + const int len = list_length (list); > + if (len == 0) > + /* Value-initialization. */ > + return false; > + else if (len > 1) > + /* If the list had more than one element, the code is ill-formed > + pre-C++20, so we should attempt to ()-init. */ > + return true; > + > + /* Lists with one element are trickier. */ > + tree elt = TREE_VALUE (list); > + > + /* For a("foo"), don't wrap the STRING_CST in { }. */ > + if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type))) > + && TREE_CODE (tree_strip_any_location_wrapper (elt)) == STRING_CST) > + return false; Hmm, yet another place we need to implement the special treatment of strings? Can't we factor this better? Could there be a general e.g. maybe_aggregate_paren_init function to turn a list into a CONSTRUCTOR that's used in various places? > + /* Don't trigger in compiler-generated code for = default. */ > + if (current_function_decl && DECL_DEFAULTED_FN (current_function_decl)) > + return false; > + > + /* Handle non-standard extensions like compound literals. */ > + return !same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (elt)); Isn't the defaulted function case caught by the same-type check? Jason