1 // RUN: %clang_cc1 -std=c++2a -verify %s 2 3 // This test is for [class.compare.default]p3 as modified and renumbered to p4 4 // by P2002R0. 5 6 namespace std { 7 struct strong_ordering { 8 int n; 9 constexpr operator int() const { return n; } 10 static const strong_ordering less, equal, greater; 11 }; 12 constexpr strong_ordering strong_ordering::less = {-1}; 13 constexpr strong_ordering strong_ordering::equal = {0}; 14 constexpr strong_ordering strong_ordering::greater = {1}; 15 } 16 17 namespace N { 18 struct A { 19 friend constexpr std::strong_ordering operator<=>(const A&, const A&) = default; 20 }; 21 22 constexpr bool (*test_a_not_found)(const A&, const A&) = &operator==; // expected-error {{undeclared}} 23 24 constexpr bool operator==(const A&, const A&) noexcept; 25 constexpr bool (*test_a)(const A&, const A&) noexcept = &operator==; 26 static_assert((*test_a)(A(), A())); 27 } 28 29 struct B1 { 30 virtual std::strong_ordering operator<=>(const B1&) const = default; 31 }; 32 bool (B1::*test_b)(const B1&) const = &B1::operator==; 33 34 struct C1 : B1 { 35 // OK, B1::operator== is virtual. 36 bool operator==(const B1&) const override; 37 }; 38 39 struct B2 { 40 std::strong_ordering operator<=>(const B2&) const = default; 41 }; 42 43 struct C2 : B2 { 44 bool operator==(const B2&) const override; // expected-error {{only virtual member functions}} 45 }; 46 47 struct D { 48 std::strong_ordering operator<=>(const D&) const; 49 virtual std::strong_ordering operator<=>(const struct E&) const = 0; 50 }; 51 struct E : D { 52 // expected-error@+2 {{only virtual member functions}} 53 // expected-note@+1 {{while declaring the corresponding implicit 'operator==' for this defaulted 'operator<=>'}} 54 std::strong_ordering operator<=>(const E&) const override = default; 55 }; 56 57 struct F { 58 [[deprecated("oh no")]] std::strong_ordering operator<=>(const F&) const = default; // expected-note 4{{deprecated}} 59 }; 60 void use_f(F f) { 61 void(f <=> f); // expected-warning {{oh no}} 62 void(f < f); // expected-warning {{oh no}} 63 void(f == f); // expected-warning {{oh no}} 64 void(f != f); // expected-warning {{oh no}} 65 } 66 67 class G { 68 // expected-note@+2 {{implicitly declared private here}} 69 // expected-note-re@+1 {{{{^}}declared private here}} 70 std::strong_ordering operator<=>(const G&) const = default; 71 public: 72 }; 73 void use_g(G g) { 74 void(g <=> g); // expected-error {{private}} 75 void(g == g); // expected-error {{private}} 76 } 77 78 struct H { 79 bool operator==(const H&) const; // expected-note {{here}} 80 constexpr std::strong_ordering operator<=>(const H&) const { return std::strong_ordering::equal; } 81 }; 82 83 struct I { 84 H h; // expected-note {{used to compare}} 85 // expected-error@+1 {{defaulted definition of three-way comparison operator cannot be declared constexpr because the corresponding implicit 'operator==' invokes a non-constexpr comparison function}} 86 constexpr std::strong_ordering operator<=>(const I&) const = default; 87 }; 88 89 struct J { 90 std::strong_ordering operator<=>(const J&) const & = default; // expected-note {{candidate function (the implicit 'operator==' for this 'operator<=>)'}} 91 friend std::strong_ordering operator<=>(const J&, const J&) = default; // expected-note {{candidate function (the implicit 'operator==' for this 'operator<=>)'}} 92 }; 93 void use_j(J j) { 94 void(j == j); // expected-error {{ambiguous}} 95 } 96 97 namespace DeleteAfterFirstDecl { 98 bool operator==(const struct Q&, const struct Q&); 99 struct Q { 100 struct X { 101 friend std::strong_ordering operator<=>(const X&, const X&); 102 } x; // expected-note {{no viable three-way comparison}} 103 // expected-error@+1 {{defaulting the corresponding implicit 'operator==' for this defaulted 'operator<=>' would delete it after its first declaration}} 104 friend std::strong_ordering operator<=>(const Q&, const Q&) = default; 105 }; 106 } 107 108 // Note, substitution here results in the second parameter of 'operator==' 109 // referring to the first parameter of 'operator==', not to the first parameter 110 // of 'operator<=>'. 111 // FIXME: Find a case where this matters (attribute enable_if?). 112 struct K { 113 friend std::strong_ordering operator<=>(const K &k, decltype(k)) = default; 114 }; 115 bool test_k = K() == K(); 116 117 namespace NoInjectionIfOperatorEqualsDeclared { 118 struct A { 119 void operator==(int); // expected-note 2{{not viable}} 120 std::strong_ordering operator<=>(const A&) const = default; 121 }; 122 bool test_a = A() == A(); // expected-error {{invalid operands}} 123 124 struct B { 125 friend void operator==(int, struct Q); // expected-note 2{{not viable}} 126 std::strong_ordering operator<=>(const B&) const = default; 127 }; 128 bool test_b = B() == B(); // expected-error {{invalid operands}} 129 130 struct C { 131 void operator==(int); // expected-note 2{{not viable}} 132 friend std::strong_ordering operator<=>(const C&, const C&) = default; 133 }; 134 bool test_c = C() == C(); // expected-error {{invalid operands}} 135 136 struct D { 137 void f() { 138 void operator==(const D&, int); 139 } 140 struct X { 141 friend void operator==(const D&, int); 142 }; 143 friend std::strong_ordering operator<=>(const D&, const D&) = default; 144 }; 145 bool test_d = D() == D(); 146 } 147