public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-7076] c++: dependent noexcept-spec on defaulted comparison op [PR96242]
@ 2022-02-06 15:48 Patrick Palka
  0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2022-02-06 15:48 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:8eb329e963593342855b6072e5692659107337b7

commit r12-7076-g8eb329e963593342855b6072e5692659107337b7
Author: Patrick Palka <ppalka@redhat.com>
Date:   Sun Feb 6 10:47:48 2022 -0500

    c++: dependent noexcept-spec on defaulted comparison op [PR96242]
    
    Here we're failing to instantiate the defaulted comparison op's
    explicit dependent noexcept-spec.  The problem is ultimately that
    mark_used relies on maybe_instantiate_noexcept to synthesize a defaulted
    comparison op, but the relevant DECL_MAYBE_DELETED fn handling in m_i_n
    is intended for such functions whose noexcept-spec wasn't explicitly
    provided (and is therefore determined via synthesis), so m_i_n just
    exits early afterwards, without considering that the synthesized fn may
    have an explicit noexcept-spec that needs instantiating.
    
    This patch fixes this issue by making mark_used directly synthesize a
    DECL_MAYBE_DELETED fn before calling maybe_instantiate_noexcept.  And
    in turn, we can properly restrict the DECL_MAYBE_DELETED fn synthesis
    in m_i_n to only those without an explicit noexcept-spec.
    
            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.  Move call to m_i_n after the
            DECL_DELETED_FN handling.
            * pt.cc (maybe_instantiate_noexcept): Restrict DECL_MAYBE_DELETED
            fn synthesis to only those with an implicit noexcept-spec, and
            return !DECL_DELETED_FN instead of !DECL_MAYBE_DELETED afterwards.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/spaceship-synth15.C: New test.

Diff:
---
 gcc/cp/decl2.cc                                | 43 +++++++++++++++-----------
 gcc/cp/pt.cc                                   | 11 ++++---
 gcc/testsuite/g++.dg/cpp2a/spaceship-synth15.C | 22 +++++++++++++
 3 files changed, 53 insertions(+), 23 deletions(-)

diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index a2aa5f1de4e..78908339989 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -5772,27 +5772,34 @@ 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 (TREE_CODE (decl) == FUNCTION_DECL
-      && DECL_DELETED_FN (decl))
-    {
-      if (DECL_ARTIFICIAL (decl)
-	  && DECL_CONV_FN_P (decl)
-	  && LAMBDA_TYPE_P (DECL_CONTEXT (decl)))
-	/* We mark a lambda conversion op as deleted if we can't
-	   generate it properly; see maybe_add_lambda_conv_op.  */
-	sorry ("converting lambda that uses %<...%> to function pointer");
-      else if (complain & tf_error)
+      if (DECL_DELETED_FN (decl))
 	{
-	  error ("use of deleted function %qD", decl);
-	  if (!maybe_explain_implicit_delete (decl))
-	    inform (DECL_SOURCE_LOCATION (decl), "declared here");
+	  if (DECL_ARTIFICIAL (decl)
+	      && DECL_CONV_FN_P (decl)
+	      && LAMBDA_TYPE_P (DECL_CONTEXT (decl)))
+	    /* We mark a lambda conversion op as deleted if we can't
+	       generate it properly; see maybe_add_lambda_conv_op.  */
+	    sorry ("converting lambda that uses %<...%> to function pointer");
+	  else if (complain & tf_error)
+	    {
+	      error ("use of deleted function %qD", decl);
+	      if (!maybe_explain_implicit_delete (decl))
+		inform (DECL_SOURCE_LOCATION (decl), "declared here");
+	    }
+	  return false;
 	}
-      return false;
+
+      if (!maybe_instantiate_noexcept (decl, complain))
+	return false;
     }
 
   if (VAR_OR_FUNCTION_DECL_P (decl) && DECL_LOCAL_DECL_P (decl))
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index f6406126b5b..c7af4712d8b 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -25981,7 +25981,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 ((!spec || UNEVALUATED_NOEXCEPT_SPEC_P (spec))
+      && DECL_MAYBE_DELETED (fn))
     {
       if (fn == current_function_decl)
 	/* We're in start_preparsed_function, keep going.  */
@@ -25990,12 +25994,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] only message in thread

only message in thread, other threads:[~2022-02-06 15:48 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-06 15:48 [gcc r12-7076] c++: dependent noexcept-spec on defaulted comparison op [PR96242] Patrick Palka

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).