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 560EF3858406 for ; Wed, 29 Sep 2021 18:14:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 560EF3858406 Received: from mail-qv1-f70.google.com (mail-qv1-f70.google.com [209.85.219.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-424-EpwkbIdPPaylxe9tUrbdKw-1; Wed, 29 Sep 2021 14:14:39 -0400 X-MC-Unique: EpwkbIdPPaylxe9tUrbdKw-1 Received: by mail-qv1-f70.google.com with SMTP id gm11-20020a056214268b00b00382a16304fbso38729qvb.14 for ; Wed, 29 Sep 2021 11:14:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:to:cc:references:from:in-reply-to :content-transfer-encoding; bh=Hrg/6IBEoumfU68kvG2oe4azYF8U090fPQzk79yAyQw=; b=TYTA8Z+boJW/Q9ynwOYc2lhg8VWJCWQ5qjLHHDtFsUoIKcF0JQl0kMy4cfhqApsA4Z zHP1a0jQ80YMueLVCJoRw4wkPDpVPW/ybwPNAS481L6RjG+NqqusY+yr3hb1+rsVSr51 gEzDvkDg6gRAzO2LXH+4DHTwFJZDawq04zDGDWCQpLOWdjfyFoYlfjmIcAt05Bd6j1bH 5WII7Gz65C8Lxqn+TxlEhZ2qhRUlgllG7eQq0V10PXRTSq165KQ7KCAzWpWJlITXrORg LgMXP39OFLZQLm20RK5sDCJlrI06o8Yh4T0fKnxSEMHGVzz7DEw4+zzInVpwiuhKYDrV RmvQ== X-Gm-Message-State: AOAM533nx6mrQZQkN4JVn1Cm+IUYX8jhXszP0bg6PNUlSmKjaKx/JpfO nGdd7vTnsP9yt9H4c4gkE33Te01Dh0AwXYy16iJAekrccEsrQxCcmgYUD44V3FgmfYNMF9nWMUB CbnAqpKVGl/V0T9Ox+g== X-Received: by 2002:a0c:b3c9:: with SMTP id b9mr1301388qvf.40.1632939279353; Wed, 29 Sep 2021 11:14:39 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxdI2qT9CbENb5I8WoAuk1WZYdGfmkBPkZ+uAFcex6rCF7PWQdMFo5tTGCwjGaaEu1RrrEUYg== X-Received: by 2002:a0c:b3c9:: with SMTP id b9mr1301347qvf.40.1632939278884; Wed, 29 Sep 2021 11:14:38 -0700 (PDT) Received: from [192.168.1.149] (130-44-159-43.s15913.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com. [130.44.159.43]) by smtp.gmail.com with ESMTPSA id q9sm314684qkj.39.2021.09.29.11.14.37 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 29 Sep 2021 11:14:38 -0700 (PDT) Message-ID: <504786a7-2453-a347-693f-8da18902bc06@redhat.com> Date: Wed, 29 Sep 2021 14:14:36 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.1.2 Subject: Re: [PATCH, v2] c++: Fix up synthetization of defaulted comparison operators on classes with bitfields [PR102490] To: Jakub Jelinek Cc: Patrick Palka , gcc-patches@gcc.gnu.org References: <20210928092455.GU304296@tucnak> <742e6e4c-f921-e12-ccc0-edc6ca19f99@idea> <28ed21ef-fac2-8e93-44f4-f2b5ab287621@idea> <38a8c792-f599-5802-ffe3-a43eaee81479@redhat.com> <20210928203439.GG304296@tucnak> From: Jason Merrill In-Reply-To: <20210928203439.GG304296@tucnak> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-8.3 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, NICE_REPLY_A, 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: Wed, 29 Sep 2021 18:14:42 -0000 On 9/28/21 16:34, Jakub Jelinek wrote: > On Tue, Sep 28, 2021 at 03:33:35PM -0400, Jason Merrill wrote: >>>> According to the function comment for defaulted_late_check, won't >>>> COMPLETE_TYPE_P (ctx) always be false here? >> >> Not for a function defaulted outside the class. >> >>> If so, I wonder if we could get away with moving this entire fragment >>> from defaulted_late_check to finish_struct_1 instead of calling >>> defaulted_late_check from finish_struct_1. >> >> The comment in check_bases_and_members says that we call it there so that >> it's before we clone [cd]tors. Probably better to leave the call there for >> other functions, just skip it for comparisons. > > So like this instead then? Just tested with dg.exp=*spaceship* so far. I was thinking to keep the checking/synthesis in defaulted_late_check, just change when it's called. That is, not to change defaulted_late_check at all, to keep the finish_struct_1 change you had in your first patch, and to change check_bases_and_members to not call defaulted_late_check for comparisons. We probably also want to assert COMPLETE_TYPE_P in build_comparison_op, at least when info.defining. BTW, the word is "synthesize". > 2021-09-28 Jakub Jelinek > > PR c++/102490 > * method.c (defaulted_late_check): Don't synthetize constexpr > defaulted comparisons. > (finish_struct_1): Synthetize constexpr defaulted comparisons here > after layout_class_type. > > * g++.dg/cpp2a/spaceship-eq11.C: New test. > * g++.dg/cpp2a/spaceship-eq12.C: New test. > > --- gcc/cp/method.c.jj 2021-09-28 11:34:10.165412477 +0200 > +++ gcc/cp/method.c 2021-09-28 22:28:23.637981709 +0200 > @@ -3158,18 +3158,7 @@ defaulted_late_check (tree fn) > special_function_kind kind = special_function_p (fn); > > if (kind == sfk_comparison) > - { > - /* If the function was declared constexpr, check that the definition > - qualifies. Otherwise we can define the function lazily. */ > - if (DECL_DECLARED_CONSTEXPR_P (fn) && !DECL_INITIAL (fn)) > - { > - /* Prevent GC. */ > - function_depth++; > - synthesize_method (fn); > - function_depth--; > - } > - return; > - } > + return; > > bool fn_const_p = (copy_fn_p (fn) == 2); > tree implicit_fn = implicitly_declare_fn (kind, ctx, fn_const_p, > --- gcc/cp/class.c.jj 2021-09-28 11:34:10.096413431 +0200 > +++ gcc/cp/class.c 2021-09-28 22:29:59.072669058 +0200 > @@ -7467,7 +7467,21 @@ finish_struct_1 (tree t) > for any static member objects of the type we're working on. */ > for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x)) > if (DECL_DECLARES_FUNCTION_P (x)) > - DECL_IN_AGGR_P (x) = false; > + { > + /* Synthetize constexpr defaulted comparisons. */ > + if (!DECL_ARTIFICIAL (x) > + && DECL_DEFAULTED_IN_CLASS_P (x) > + && special_function_p (x) == sfk_comparison > + && DECL_DECLARED_CONSTEXPR_P (x) > + && !DECL_INITIAL (x)) > + { > + /* Prevent GC. */ > + function_depth++; > + synthesize_method (x); > + function_depth--; > + } > + DECL_IN_AGGR_P (x) = false; > + } > else if (VAR_P (x) && TREE_STATIC (x) > && TREE_TYPE (x) != error_mark_node > && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t)) > --- gcc/testsuite/g++.dg/cpp2a/spaceship-eq11.C.jj 2021-09-28 22:27:40.524574708 +0200 > +++ gcc/testsuite/g++.dg/cpp2a/spaceship-eq11.C 2021-09-28 22:27:40.524574708 +0200 > @@ -0,0 +1,43 @@ > +// PR c++/102490 > +// { dg-do run { target c++20 } } > + > +struct A > +{ > + unsigned char a : 1; > + unsigned char b : 1; > + constexpr bool operator== (const A &) const = default; > +}; > + > +struct B > +{ > + unsigned char a : 8; > + int : 0; > + unsigned char b : 7; > + constexpr bool operator== (const B &) const = default; > +}; > + > +struct C > +{ > + unsigned char a : 3; > + unsigned char b : 1; > + constexpr bool operator== (const C &) const = default; > +}; > + > +void > +foo (C &x, int y) > +{ > + x.b = y; > +} > + > +int > +main () > +{ > + A a{}, b{}; > + B c{}, d{}; > + C e{}, f{}; > + a.b = 1; > + d.b = 1; > + foo (e, 0); > + foo (f, 1); > + return a == b || c == d || e == f; > +} > --- gcc/testsuite/g++.dg/cpp2a/spaceship-eq12.C.jj 2021-09-28 22:27:40.524574708 +0200 > +++ gcc/testsuite/g++.dg/cpp2a/spaceship-eq12.C 2021-09-28 22:27:40.524574708 +0200 > @@ -0,0 +1,5 @@ > +// PR c++/102490 > +// { dg-do run { target c++20 } } > +// { dg-options "-O2" } > + > +#include "spaceship-eq11.C" > > > Jakub >