diff mbox series

[pushed] c++: Redeclaration of implicit operator== [PR94583]

Message ID 20200428183702.3630-1-jason@redhat.com
State New
Headers show
Series [pushed] c++: Redeclaration of implicit operator== [PR94583] | expand

Commit Message

Jason Merrill April 28, 2020, 6:37 p.m. UTC
My last patch rejected a namespace-scope declaration of the
implicitly-declared friend operator== before the class, but redeclaring it
after the class should be OK.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog
2020-04-28  Jason Merrill  <jason@redhat.com>

	PR c++/94583
	* decl.c (use_eh_spec_block): Check nothrow type after
	DECL_DEFAULTED_FN.
	* pt.c (maybe_instantiate_noexcept): Call synthesize_method for
	DECL_MAYBE_DELETED fns here.
	* decl2.c (mark_used): Not here.
	* method.c (get_defaulted_eh_spec): Reject DECL_MAYBE_DELETED here.
---
 gcc/cp/cp-tree.h                              |  2 +-
 gcc/cp/decl.c                                 |  4 ++--
 gcc/cp/decl2.c                                | 11 -----------
 gcc/cp/method.c                               | 11 ++++-------
 gcc/cp/pt.c                                   | 12 ++++++++++++
 gcc/testsuite/g++.dg/cpp2a/spaceship-synth7.C |  9 +++++++++
 6 files changed, 28 insertions(+), 21 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/spaceship-synth7.C


base-commit: 34f6b14ff33e0c64b3a4a1a2cd871df715d69151
diff mbox series

Patch

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index fff0016b3aa..e115a8a1d25 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3169,7 +3169,7 @@  struct GTY(()) lang_decl {
   (LANG_DECL_FN_CHECK (NODE)->has_dependent_explicit_spec_p)
 
 /* Nonzero for a defaulted FUNCTION_DECL for which we haven't decided yet if
-   it's deleted.  */
+   it's deleted; we will decide in synthesize_method.  */
 #define DECL_MAYBE_DELETED(NODE) \
   (LANG_DECL_FN_CHECK (NODE)->maybe_deleted)
 
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index cf855dae909..4c0ae1cfa2e 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -16503,7 +16503,6 @@  use_eh_spec_block (tree fn)
 {
   return (flag_exceptions && flag_enforce_eh_specs
 	  && !processing_template_decl
-	  && !type_throw_all_p (TREE_TYPE (fn))
 	  /* We insert the EH_SPEC_BLOCK only in the original
 	     function; then, it is copied automatically to the
 	     clones.  */
@@ -16516,7 +16515,8 @@  use_eh_spec_block (tree fn)
 	     not creating the EH_SPEC_BLOCK we save a little memory,
 	     and we avoid spurious warnings about unreachable
 	     code.  */
-	  && !DECL_DEFAULTED_FN (fn));
+	  && !DECL_DEFAULTED_FN (fn)
+	  && !type_throw_all_p (TREE_TYPE (fn)));
 }
 
 /* Helper function to push ARGS into the current lexical scope.  DECL
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index ac65529a01d..8d3ac31a0c9 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -5512,17 +5512,6 @@  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_MAYBE_DELETED (decl))
-    {
-      /* ??? Switch other defaulted functions to use DECL_MAYBE_DELETED?  */
-      gcc_assert (special_function_p (decl) == sfk_comparison);
-
-      ++function_depth;
-      synthesize_method (decl);
-      --function_depth;
-    }
-
   if (TREE_CODE (decl) == FUNCTION_DECL
       && !maybe_instantiate_noexcept (decl, complain))
     return false;
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 2fb0de288a2..fb2dd47013f 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -2411,16 +2411,13 @@  synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
 tree
 get_defaulted_eh_spec (tree decl, tsubst_flags_t complain)
 {
+  /* For DECL_MAYBE_DELETED this should already have been handled by
+     synthesize_method.  */
+  gcc_assert (!DECL_MAYBE_DELETED (decl));
+
   if (DECL_CLONED_FUNCTION_P (decl))
     decl = DECL_CLONED_FUNCTION (decl);
   special_function_kind sfk = special_function_p (decl);
-  if (sfk == sfk_comparison)
-    {
-      /* We're in synthesize_method. Start with NULL_TREE, build_comparison_op
-	 will adjust as needed.  */
-      gcc_assert (decl == current_function_decl);
-      return NULL_TREE;
-    }
   tree ctype = DECL_CONTEXT (decl);
   tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
   tree parm_type = TREE_VALUE (parms);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 66308a2d295..ba22d9ec538 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -25180,6 +25180,18 @@  maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
       && (!flag_noexcept_type || type_dependent_expression_p (fn)))
     return true;
 
+  if (DECL_MAYBE_DELETED (fn))
+    {
+      if (fn == current_function_decl)
+	/* We're in start_preparsed_function, keep going.  */
+	return true;
+
+      ++function_depth;
+      synthesize_method (fn);
+      --function_depth;
+      return !DECL_MAYBE_DELETED (fn);
+    }
+
   if (DECL_CLONED_FUNCTION_P (fn))
     fn = DECL_CLONED_FUNCTION (fn);
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-synth7.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth7.C
new file mode 100644
index 00000000000..86b661ca6e0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth7.C
@@ -0,0 +1,9 @@ 
+// PR c++/94583
+// { dg-do compile { target c++2a } }
+
+namespace std { struct strong_ordering { }; }
+
+struct Q {
+  friend std::strong_ordering operator<=>(const Q&, const Q&) = default;
+};
+bool operator==(const Q&, const Q&) noexcept;