aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-04-24 16:27:26 -0400
committerJason Merrill <jason@redhat.com>2020-04-25 00:17:30 -0400
commit352811870d7d7edcca109ef50822e26ca7ef2b36 (patch)
tree10785d379f68b116876f6b29690ad2fdeb98a628
parent5e7e8b98f49eda9ffb9817d97975a211c87c5a53 (diff)
downloadgcc-352811870d7d7edcca109ef50822e26ca7ef2b36.zip
gcc-352811870d7d7edcca109ef50822e26ca7ef2b36.tar.gz
gcc-352811870d7d7edcca109ef50822e26ca7ef2b36.tar.bz2
c++: implicit operator== with previous decl [PR94583]
P2085 clarified that a defaulted comparison operator must be the first declaration of the function. Rejecting that avoids the ICE trying to compare the noexcept-specifications. gcc/cp/ChangeLog 2020-04-24 Jason Merrill <jason@redhat.com> PR c++/94583 * decl.c (redeclaration_error_message): Reject defaulted comparison operator that has been previously declared.
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/decl.c8
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/spaceship-synth6.C11
3 files changed, 25 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2a5b417..f0c6278 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2020-04-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/94583
+ * decl.c (redeclaration_error_message): Reject defaulted comparison
+ operator that has been previously declared.
+
2020-04-25 Patrick Palka <ppalka@redhat.com>
* parser.c (cp_parser_diagnose_invalid_type_name): Suggest enabling
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index c8c2f08..31b5884 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2972,6 +2972,14 @@ redeclaration_error_message (tree newdecl, tree olddecl)
}
}
+ /* [class.compare.default]: A definition of a comparison operator as
+ defaulted that appears in a class shall be the first declaration of
+ that function. */
+ special_function_kind sfk = special_function_p (olddecl);
+ if (sfk == sfk_comparison && DECL_DEFAULTED_FN (newdecl))
+ return G_("comparison operator %q+D defaulted after "
+ "its first declaration");
+
check_abi_tag_redeclaration
(olddecl, lookup_attribute ("abi_tag", DECL_ATTRIBUTES (olddecl)),
lookup_attribute ("abi_tag", DECL_ATTRIBUTES (newdecl)));
diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-synth6.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth6.C
new file mode 100644
index 0000000..e8296bb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth6.C
@@ -0,0 +1,11 @@
+// PR c++/94583
+// { dg-do compile { target c++2a } }
+
+namespace std { struct strong_ordering { }; }
+
+bool operator==(const struct Q&, const struct Q&);
+struct Q {
+ // { dg-error "defaulted after its first declaration" "" { target *-*-* } .+1 }
+ friend std::strong_ordering operator<=>(const Q&, const Q&) = default;
+};
+bool b = Q() == Q();