[PATCH] D95409: [clang] implicitly delete space ship operator with function pointers
Matheus Izvekov via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 26 13:22:33 PST 2021
mizvekov updated this revision to Diff 319400.
mizvekov added a comment.
added tests
adds test that will catch original bug
also adds some tests on default equality/relational operators
this last one would have caught the issue of not accepting equality
operator for function pointers, had I not remembered about it :)
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D95409/new/
https://reviews.llvm.org/D95409
Files:
clang/lib/Sema/SemaDeclCXX.cpp
clang/test/CXX/class/class.compare/class.compare.default/p6.cpp
clang/test/CXX/class/class.compare/class.spaceship/p4.cpp
Index: clang/test/CXX/class/class.compare/class.spaceship/p4.cpp
===================================================================
--- /dev/null
+++ clang/test/CXX/class/class.compare/class.spaceship/p4.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+namespace std {
+class partial_ordering {
+ int n;
+ constexpr partial_ordering(int n) : n(n) {}
+
+public:
+ static const partial_ordering less, equivalent, greater, unordered;
+ bool operator!=(int) { return n != 0; }
+};
+constexpr partial_ordering partial_ordering::less{-1},
+ partial_ordering::equivalent{0}, partial_ordering::greater{1},
+ partial_ordering::unordered{2};
+} // namespace std
+
+struct A {
+ auto operator<=>(A const &) const = default; // expected-warning {{explicitly defaulted three-way comparison operator is implicitly deleted}}
+ const int &a = 0; // expected-note {{defaulted 'operator<=>' is implicitly deleted because class 'A' has a reference member}}
+};
+
+struct B {
+ auto operator<=>(B const &) const = default; // expected-warning {{explicitly defaulted three-way comparison operator is implicitly deleted}}
+ void (*a)(); // expected-note {{defaulted 'operator<=>' is implicitly deleted because there is no viable comparison function for member 'a'}}
+};
+
+struct C {
+ auto operator<=>(C const &) const = default; // expected-warning {{explicitly defaulted three-way comparison operator is implicitly deleted}}
+ void (C::*a)(); // expected-note {{defaulted 'operator<=>' is implicitly deleted because there is no viable comparison function for member 'a'}}
+};
+
+struct D {
+ auto operator<=>(D const &) const = default; // expected-warning {{explicitly defaulted three-way comparison operator is implicitly deleted}}
+ int D::*a; // expected-note {{defaulted 'operator<=>' is implicitly deleted because there is no viable comparison function for member 'a'}}
+};
Index: clang/test/CXX/class/class.compare/class.compare.default/p6.cpp
===================================================================
--- /dev/null
+++ clang/test/CXX/class/class.compare/class.compare.default/p6.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+struct A {
+ bool operator==(A const &) const = default; // expected-warning {{explicitly defaulted equality comparison operator is implicitly deleted}}
+ bool operator<(A const &) const = default; // expected-warning {{explicitly defaulted relational comparison operator is implicitly deleted}}
+ // expected-note at -1 {{defaulted 'operator<' is implicitly deleted because there is no viable comparison function}}
+ const int &a = 0; // expected-note {{defaulted 'operator==' is implicitly deleted because class 'A' has a reference member}}
+};
+
+struct B {
+ bool operator==(B const &) const = default;
+ bool operator<(B const &) const = default; // expected-warning {{explicitly defaulted relational comparison operator is implicitly deleted}}
+ // expected-note at -1 {{defaulted 'operator<' is implicitly deleted because there is no viable comparison function}}
+ void (*a)();
+};
+
+struct C {
+ bool operator==(C const &) const = default;
+ bool operator<(C const &) const = default; // expected-warning {{explicitly defaulted relational comparison operator is implicitly deleted}}
+ // expected-note at -1 {{defaulted 'operator<' is implicitly deleted because there is no viable comparison function}}
+ void (C::*a)();
+};
+
+struct D {
+ bool operator==(D const &) const = default;
+ bool operator<(D const &) const = default; // expected-warning {{explicitly defaulted relational comparison operator is implicitly deleted}}
+ // expected-note at -1 {{defaulted 'operator<' is implicitly deleted because there is no viable comparison function}}
+ int D::*a;
+};
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -7677,7 +7677,8 @@
if (Args[0]->getType()->isOverloadableType())
S.LookupOverloadedBinOp(CandidateSet, OO, Fns, Args);
- else {
+ else if (OO == OO_EqualEqual ||
+ !Args[0]->getType()->isFunctionPointerType()) {
// FIXME: We determine whether this is a valid expression by checking to
// see if there's a viable builtin operator candidate for it. That isn't
// really what the rules ask us to do, but should give the right results.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D95409.319400.patch
Type: text/x-patch
Size: 4545 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210126/40f6a48e/attachment-0001.bin>
More information about the cfe-commits
mailing list