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 ESMTPS id 099FF3858D20 for ; Fri, 4 Feb 2022 22:00:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 099FF3858D20 Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-28-MSdgj-P1NfCZCz1tKJ8AiQ-1; Fri, 04 Feb 2022 17:00:26 -0500 X-MC-Unique: MSdgj-P1NfCZCz1tKJ8AiQ-1 Received: by mail-qk1-f198.google.com with SMTP id d130-20020a379b88000000b004e11e7b51c4so4324263qke.17 for ; Fri, 04 Feb 2022 14:00:26 -0800 (PST) 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=g+RxStwVmsPJcd6Lc2xUZ/wScRpq0iIHWNrSluHANbE=; b=zuToOTmOhn/GUFlUtYF1VwnnYECORlVp1ppUeD9t98xd6oKHjd28PGOlNkqSIL1WCx sX9PD3KKF6vIzWtFPPdWPpkQWPA6AOSy9oKliu55kCNNhpXmpYFvHh+DXplGo0dfUEgF XZX7BNtneXnb8UNxuZsW7fiW8ggazDPGjE2ImlTcJdkrs4YTTGWniMNZqvVhj5bZRl96 +U0cJ8y3Bn5cZmd5zgK3etzcP/Xj9lpcrGXFdKku8nxefY19VCKLWfjceAog9XcwNdKg 6I5xji4rMuGn7hKNnY9eUbdCupq0FTtkfsP1sXWi4r/ZuIc/aWoBd2Dv5zjOMbeZodiu UEQw== X-Gm-Message-State: AOAM532IQbGqsdkwVya0pFJdcWBppN0MIm6bI5FXQF6IpITAL0KOsMDJ eu2TrOv47F9nPsrQlMcXI9OpNLlivcXPEc0KTdmLjVhXDq8YuhwSYFk2OexDEX2s0MHADz4CehM GPaqI6kI60pGxKdSa0Q== X-Received: by 2002:a05:622a:1a84:: with SMTP id s4mr822802qtc.133.1644012025939; Fri, 04 Feb 2022 14:00:25 -0800 (PST) X-Google-Smtp-Source: ABdhPJwQYRKKen8Grvba2VQG3L38cdztDQv4M0gd9LmyutMf2oZ8G5DWzLpx38QjHxxFWorceqVFlQ== X-Received: by 2002:a05:622a:1a84:: with SMTP id s4mr822786qtc.133.1644012025572; Fri, 04 Feb 2022 14:00:25 -0800 (PST) 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 u17sm1728038qki.12.2022.02.04.14.00.23 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 04 Feb 2022 14:00:24 -0800 (PST) Message-ID: <7c90171a-bba8-4643-d98d-f963da943d35@redhat.com> Date: Fri, 4 Feb 2022 17:00:23 -0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.5.1 Subject: Re: [PATCH] c++: conditional noexcept-spec on defaulted comparison op [PR96242] To: Patrick Palka Cc: gcc-patches@gcc.gnu.org References: <20220203195838.409426-1-ppalka@redhat.com> <152576a5-c950-b21c-edfd-a15a7b0305b3@redhat.com> <6f99b484-a501-ba99-ffd1-d124c6c48a72@idea> <018e7a37-8bf9-9b9d-d6fe-9735263ba086@idea> From: Jason Merrill In-Reply-To: <018e7a37-8bf9-9b9d-d6fe-9735263ba086@idea> 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=-12.9 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_LOW, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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: Fri, 04 Feb 2022 22:00:32 -0000 On 2/4/22 12:04, Patrick Palka wrote: > On Thu, 3 Feb 2022, Jason Merrill wrote: > >> On 2/3/22 16:06, Patrick Palka wrote: >>> On Thu, 3 Feb 2022, Jason Merrill wrote: >>> >>>> On 2/3/22 14:58, Patrick Palka wrote: >>>>> When synthesizing a defaulted comparison op from >>>>> maybe_instantiate_noexcept, we seem to be forgetting to instantiate the >>>>> noexcept-spec afterwards. >>>> >>>> Hmm, there shouldn't be any need to instantiate the noexcept-spec >>>> afterwards, >>>> it should have been set by ~comp_info. >>> >>> It appears the comp_info class sets the noexcept-spec only if the >>> comparison function hasn't been declared with an explicit noexcept-spec. >>> Otherwise the class doesn't touch the noexcept-spec, and it remains a >>> DEFERRED_NOEXCEPT with non-NULL DEFERRED_NOEXCEPT_PATTERN. >> >> Ah, I see. So perhaps we should entirely skip the current DECL_MAYBE_DELETED >> handling in maybe_instantiate_noexcept if we have DEFERRED_NOEXCEPT with >> non-null DEFERRED_NOEXCEPT_PATTERN (which seems to want another macro)? > > Hmm, I tried something to that effect but it looks like mark_used relies > solely on the DECL_MAYBE_DELETED handling in maybe_instantiate_noexcept > to determine deletedness of a defaulted comparison operator (via trying > to synthesize it). So by sometimes sidestepping this handling, we end > up failing to diagnose the use of the deleted defaulted <=> in e.g.: > > #include > > struct A { }; > > template > struct X { > auto operator<=>(const X&) const noexcept(B) = default; > A a; > }; > > X x_t; > auto c = x_t <=> x_t; // should be error: use of deleted <=> b/c A lacks <=> > > In light of this, I suppose mark_used should directly perform > DECL_MAYBE_DELETED synthesization of its own? > > And it looks like DECL_MAYBE_DELETED is always false after doing > maybe_synthesize_method, so I think maybe_instantiate_noexcept should > return !DECL_DELETED_FN instead of !DECL_MAYBE_DELETED after synthesization. > > How does this look? Lightly tested so far, bootstrap and regtesting in progress. > > -- >8 -- > > PR c++/96242 > > gcc/cp/ChangeLog: > > * decl2.cc (mark_used): Directly synthesize a DECL_MAYBE_DELETED > fn by calling maybe_synthesize_method instead of relying on > maybe_instantiate_noexcept. > * pt.cc (maybe_instantiate_noexcept): Restrict DECL_MAYBE_DELETED > synthesization to only fns with an implicit noexcept-spec, and > return !DECL_DELETED_FN instead of !DECL_MAYBE_DELETED afteward. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/spaceship-synth15.C: New test. > --- > gcc/cp/decl2.cc | 17 ++++++++++---- > gcc/cp/pt.cc | 11 +++++----- > .../g++.dg/cpp2a/spaceship-synth15.C | 22 +++++++++++++++++++ > 3 files changed, 41 insertions(+), 9 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/spaceship-synth15.C > > diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc > index a2aa5f1de4e..4d3798d02fe 100644 > --- a/gcc/cp/decl2.cc > +++ b/gcc/cp/decl2.cc > @@ -5772,10 +5772,19 @@ mark_used (tree decl, tsubst_flags_t complain) > if (TREE_CODE (decl) == CONST_DECL) > used_types_insert (DECL_CONTEXT (decl)); > > - if (TREE_CODE (decl) == FUNCTION_DECL > - && !DECL_DELETED_FN (decl) > - && !maybe_instantiate_noexcept (decl, complain)) > - return false; > + if (TREE_CODE (decl) == FUNCTION_DECL) > + { > + if (DECL_MAYBE_DELETED (decl)) > + { > + ++function_depth; > + maybe_synthesize_method (decl); > + --function_depth; > + } > + > + if (!DECL_DELETED_FN (decl) > + && !maybe_instantiate_noexcept (decl, complain)) > + return false; At this point we might move the call to maybe_instantiate_noexcept after the DECL_DELETED_FN handling just below. OK either way. > + } > > if (TREE_CODE (decl) == FUNCTION_DECL > && DECL_DELETED_FN (decl)) > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index d219bba6ac1..584c752529b 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -25982,7 +25982,11 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) > && (!flag_noexcept_type || type_dependent_expression_p (fn))) > return true; > > - if (DECL_MAYBE_DELETED (fn)) > + tree fntype = TREE_TYPE (fn); > + tree spec = TYPE_RAISES_EXCEPTIONS (fntype); > + > + if (DECL_MAYBE_DELETED (fn) > + && (!spec || UNEVALUATED_NOEXCEPT_SPEC_P (spec))) > { > if (fn == current_function_decl) > /* We're in start_preparsed_function, keep going. */ > @@ -25991,12 +25995,9 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) > ++function_depth; > maybe_synthesize_method (fn); > --function_depth; > - return !DECL_MAYBE_DELETED (fn); > + return !DECL_DELETED_FN (fn); > } > > - tree fntype = TREE_TYPE (fn); > - tree spec = TYPE_RAISES_EXCEPTIONS (fntype); > - > if (!spec || !TREE_PURPOSE (spec)) > return true; > > diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-synth15.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth15.C > new file mode 100644 > index 00000000000..00ea6c10474 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth15.C > @@ -0,0 +1,22 @@ > +// PR c++/96242 > +// { dg-do compile { target c++20 } } > + > +#include > + > +template > +struct X { > + auto operator<=>(const X&) const noexcept(B) = default; > + bool operator==(const X&) const noexcept(!B) = default; > +}; > + > +X x_t; > +static_assert(noexcept(x_t <=> x_t)); > +static_assert(noexcept(x_t < x_t)); > +static_assert(!noexcept(x_t == x_t)); > +static_assert(!noexcept(x_t != x_t)); > + > +X x_f; > +static_assert(!noexcept(x_f <=> x_f)); > +static_assert(!noexcept(x_f < x_f)); > +static_assert(noexcept(x_f == x_f)); > +static_assert(noexcept(x_f != x_f));