aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-04-28 12:27:27 -0400
committerJason Merrill <jason@redhat.com>2020-04-28 14:37:36 -0400
commitbce54ed494fd0e61f41986e2bdbcfb2d2a3a1cf1 (patch)
tree6f38b1eb92da669605d2d65982ae70939c525b64 /gcc
parent5eae0ac76dcb6aac1d1d6c4edd8852e0035792e4 (diff)
downloadgcc-bce54ed494fd0e61f41986e2bdbcfb2d2a3a1cf1.zip
gcc-bce54ed494fd0e61f41986e2bdbcfb2d2a3a1cf1.tar.gz
gcc-bce54ed494fd0e61f41986e2bdbcfb2d2a3a1cf1.tar.bz2
c++: Redeclaration of implicit operator== [PR94583]
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. 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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c4
-rw-r--r--gcc/cp/decl2.c11
-rw-r--r--gcc/cp/method.c11
-rw-r--r--gcc/cp/pt.c12
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/spaceship-synth7.C9
7 files changed, 38 insertions, 21 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index dd8ee21..8728389 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+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.
+
2020-04-28 Iain Sandoe <iain@sandoe.co.uk>
PR c++/94760
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index fff0016..e115a8a 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 cf855da..4c0ae1c 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 ac65529..8d3ac31 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -5513,17 +5513,6 @@ mark_used (tree decl, tsubst_flags_t complain)
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 2fb0de2..fb2dd47 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 66308a2..ba22d9e 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 0000000..86b661c
--- /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;