* [PATCH] c++: conditional noexcept-spec on defaulted comparison op [PR96242] @ 2022-02-03 19:58 Patrick Palka 2022-02-03 20:26 ` Jason Merrill 0 siblings, 1 reply; 6+ messages in thread From: Patrick Palka @ 2022-02-03 19:58 UTC (permalink / raw) To: gcc-patches When synthesizing a defaulted comparison op from maybe_instantiate_noexcept, we seem to be forgetting to instantiate the noexcept-spec afterwards. Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk and perhaps 11? PR c++/96242 gcc/cp/ChangeLog: * pt.cc (maybe_instantiate_noexcept): Keep going after successfully synthesizing a DECL_MAYBE_DELETED fn. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/spaceship-synth15.C: New test. --- gcc/cp/pt.cc | 3 ++- .../g++.dg/cpp2a/spaceship-synth15.C | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/spaceship-synth15.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 6dd64101ced..03345ed3ed3 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -25986,7 +25986,8 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) ++function_depth; maybe_synthesize_method (fn); --function_depth; - return !DECL_MAYBE_DELETED (fn); + if (DECL_MAYBE_DELETED (fn)) + return false; } tree fntype = TREE_TYPE (fn); 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 <compare> + +template<bool B> +struct X { + auto operator<=>(const X&) const noexcept(B) = default; + bool operator==(const X&) const noexcept(!B) = default; +}; + +X<true> 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<false> 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)); -- 2.35.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] c++: conditional noexcept-spec on defaulted comparison op [PR96242] 2022-02-03 19:58 [PATCH] c++: conditional noexcept-spec on defaulted comparison op [PR96242] Patrick Palka @ 2022-02-03 20:26 ` Jason Merrill 2022-02-03 21:06 ` Patrick Palka 0 siblings, 1 reply; 6+ messages in thread From: Jason Merrill @ 2022-02-03 20:26 UTC (permalink / raw) To: Patrick Palka, gcc-patches 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. > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > trunk and perhaps 11? > > PR c++/96242 > > gcc/cp/ChangeLog: > > * pt.cc (maybe_instantiate_noexcept): Keep going after > successfully synthesizing a DECL_MAYBE_DELETED fn. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/spaceship-synth15.C: New test. > --- > gcc/cp/pt.cc | 3 ++- > .../g++.dg/cpp2a/spaceship-synth15.C | 22 +++++++++++++++++++ > 2 files changed, 24 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/spaceship-synth15.C > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index 6dd64101ced..03345ed3ed3 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -25986,7 +25986,8 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) > ++function_depth; > maybe_synthesize_method (fn); > --function_depth; > - return !DECL_MAYBE_DELETED (fn); > + if (DECL_MAYBE_DELETED (fn)) > + return false; > } > > tree fntype = TREE_TYPE (fn); > 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 <compare> > + > +template<bool B> > +struct X { > + auto operator<=>(const X&) const noexcept(B) = default; > + bool operator==(const X&) const noexcept(!B) = default; > +}; > + > +X<true> 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<false> 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)); ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] c++: conditional noexcept-spec on defaulted comparison op [PR96242] 2022-02-03 20:26 ` Jason Merrill @ 2022-02-03 21:06 ` Patrick Palka 2022-02-03 21:38 ` Jason Merrill 0 siblings, 1 reply; 6+ messages in thread From: Patrick Palka @ 2022-02-03 21:06 UTC (permalink / raw) To: Jason Merrill; +Cc: Patrick Palka, gcc-patches 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. > > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > > trunk and perhaps 11? > > > > PR c++/96242 > > > > gcc/cp/ChangeLog: > > > > * pt.cc (maybe_instantiate_noexcept): Keep going after > > successfully synthesizing a DECL_MAYBE_DELETED fn. > > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/cpp2a/spaceship-synth15.C: New test. > > --- > > gcc/cp/pt.cc | 3 ++- > > .../g++.dg/cpp2a/spaceship-synth15.C | 22 +++++++++++++++++++ > > 2 files changed, 24 insertions(+), 1 deletion(-) > > create mode 100644 gcc/testsuite/g++.dg/cpp2a/spaceship-synth15.C > > > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > > index 6dd64101ced..03345ed3ed3 100644 > > --- a/gcc/cp/pt.cc > > +++ b/gcc/cp/pt.cc > > @@ -25986,7 +25986,8 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t > > complain) > > ++function_depth; > > maybe_synthesize_method (fn); > > --function_depth; > > - return !DECL_MAYBE_DELETED (fn); > > + if (DECL_MAYBE_DELETED (fn)) > > + return false; > > } > > tree fntype = TREE_TYPE (fn); > > 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 <compare> > > + > > +template<bool B> > > +struct X { > > + auto operator<=>(const X&) const noexcept(B) = default; > > + bool operator==(const X&) const noexcept(!B) = default; > > +}; > > + > > +X<true> 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<false> 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)); > > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] c++: conditional noexcept-spec on defaulted comparison op [PR96242] 2022-02-03 21:06 ` Patrick Palka @ 2022-02-03 21:38 ` Jason Merrill 2022-02-04 17:04 ` Patrick Palka 0 siblings, 1 reply; 6+ messages in thread From: Jason Merrill @ 2022-02-03 21:38 UTC (permalink / raw) To: Patrick Palka; +Cc: gcc-patches 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)? >>> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for >>> trunk and perhaps 11? >>> >>> PR c++/96242 >>> >>> gcc/cp/ChangeLog: >>> >>> * pt.cc (maybe_instantiate_noexcept): Keep going after >>> successfully synthesizing a DECL_MAYBE_DELETED fn. >>> >>> gcc/testsuite/ChangeLog: >>> >>> * g++.dg/cpp2a/spaceship-synth15.C: New test. >>> --- >>> gcc/cp/pt.cc | 3 ++- >>> .../g++.dg/cpp2a/spaceship-synth15.C | 22 +++++++++++++++++++ >>> 2 files changed, 24 insertions(+), 1 deletion(-) >>> create mode 100644 gcc/testsuite/g++.dg/cpp2a/spaceship-synth15.C >>> >>> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc >>> index 6dd64101ced..03345ed3ed3 100644 >>> --- a/gcc/cp/pt.cc >>> +++ b/gcc/cp/pt.cc >>> @@ -25986,7 +25986,8 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t >>> complain) >>> ++function_depth; >>> maybe_synthesize_method (fn); >>> --function_depth; >>> - return !DECL_MAYBE_DELETED (fn); >>> + if (DECL_MAYBE_DELETED (fn)) >>> + return false; >>> } >>> tree fntype = TREE_TYPE (fn); >>> 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 <compare> >>> + >>> +template<bool B> >>> +struct X { >>> + auto operator<=>(const X&) const noexcept(B) = default; >>> + bool operator==(const X&) const noexcept(!B) = default; >>> +}; >>> + >>> +X<true> 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<false> 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)); >> >> > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] c++: conditional noexcept-spec on defaulted comparison op [PR96242] 2022-02-03 21:38 ` Jason Merrill @ 2022-02-04 17:04 ` Patrick Palka 2022-02-04 22:00 ` Jason Merrill 0 siblings, 1 reply; 6+ messages in thread From: Patrick Palka @ 2022-02-04 17:04 UTC (permalink / raw) To: Jason Merrill; +Cc: Patrick Palka, gcc-patches 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 <compare> struct A { }; template<bool B> struct X { auto operator<=>(const X&) const noexcept(B) = default; A a; }; X<true> 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; + } 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 <compare> + +template<bool B> +struct X { + auto operator<=>(const X&) const noexcept(B) = default; + bool operator==(const X&) const noexcept(!B) = default; +}; + +X<true> 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<false> 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)); -- 2.35.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] c++: conditional noexcept-spec on defaulted comparison op [PR96242] 2022-02-04 17:04 ` Patrick Palka @ 2022-02-04 22:00 ` Jason Merrill 0 siblings, 0 replies; 6+ messages in thread From: Jason Merrill @ 2022-02-04 22:00 UTC (permalink / raw) To: Patrick Palka; +Cc: gcc-patches 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 <compare> > > struct A { }; > > template<bool B> > struct X { > auto operator<=>(const X&) const noexcept(B) = default; > A a; > }; > > X<true> 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 <compare> > + > +template<bool B> > +struct X { > + auto operator<=>(const X&) const noexcept(B) = default; > + bool operator==(const X&) const noexcept(!B) = default; > +}; > + > +X<true> 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<false> 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)); ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-02-04 22:00 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-02-03 19:58 [PATCH] c++: conditional noexcept-spec on defaulted comparison op [PR96242] Patrick Palka 2022-02-03 20:26 ` Jason Merrill 2022-02-03 21:06 ` Patrick Palka 2022-02-03 21:38 ` Jason Merrill 2022-02-04 17:04 ` Patrick Palka 2022-02-04 22:00 ` Jason Merrill
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).