1 // RUN: %clang_cc1 -std=c++2a -verify %s 2 3 struct A1 { 4 int x; 5 int &y; // expected-note 9{{because class 'A1' has a reference member}} 6 7 bool operator==(const A1&) const = default; // expected-warning {{implicitly deleted}} expected-note 2{{deleted here}} 8 bool operator<=>(const A1&) const = default; // expected-warning {{implicitly deleted}} expected-note 5{{deleted here}} 9 }; 10 struct A2 { 11 int x; 12 int &y; 13 14 bool operator==(const A2&) const; 15 bool operator!=(const A2&) const = default; 16 17 int operator<=>(const A2&) const; 18 bool operator<(const A2&) const = default; 19 bool operator<=(const A2&) const = default; 20 bool operator>(const A2&) const = default; 21 bool operator>=(const A2&) const = default; 22 }; 23 void f(A1 a) { 24 void(a == a); // expected-error {{deleted}} 25 void(a != a); // expected-error {{deleted}} 26 void(a <=> a); // expected-error {{deleted}} 27 void(a < a); // expected-error {{deleted}} 28 void(a <= a); // expected-error {{deleted}} 29 void(a > a); // expected-error {{deleted}} 30 void(a >= a); // expected-error {{deleted}} 31 } 32 void f(A2 a) { 33 void(a == a); 34 void(a != a); 35 void(a <=> a); 36 void(a < a); 37 void(a <= a); 38 void(a > a); 39 void(a >= a); 40 } 41 42 struct A3 { 43 int &x; // expected-note {{because class 'A3' has a reference member}} 44 45 bool operator==(const A3 &) const = default; // expected-warning {{implicitly deleted}} 46 bool operator<(const A3 &) const = default; // expected-warning {{implicitly deleted}} 47 // expected-note@-1 {{because there is no viable three-way comparison function for 'A3'}} 48 }; 49 50 struct B1 { 51 struct { 52 int x; 53 int &y; // expected-note 2{{because class 'B1' has a reference member}} 54 }; 55 56 bool operator==(const B1&) const = default; // expected-warning {{implicitly deleted}} 57 bool operator<=>(const B1&) const = default; // expected-warning {{implicitly deleted}} 58 }; 59 60 struct B2 { 61 struct { 62 int x; 63 int &y; 64 }; 65 66 bool operator==(const B2&) const; 67 bool operator!=(const B2&) const = default; 68 69 bool operator<=>(const B2&) const; 70 bool operator<(const B2&) const = default; 71 bool operator<=(const B2&) const = default; 72 bool operator>(const B2&) const = default; 73 bool operator>=(const B2&) const = default; 74 }; 75 76 union C1 { 77 int a; 78 79 bool operator==(const C1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'C1' is a union }} 80 bool operator<=>(const C1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'C1' is a union }} 81 }; 82 83 union C2 { 84 int a; 85 86 bool operator==(const C2&) const; 87 bool operator!=(const C2&) const = default; 88 89 bool operator<=>(const C2&) const; 90 bool operator<(const C2&) const = default; 91 bool operator<=(const C2&) const = default; 92 bool operator>(const C2&) const = default; 93 bool operator>=(const C2&) const = default; 94 }; 95 96 struct D1 { 97 union { 98 int a; 99 }; 100 101 bool operator==(const D1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'D1' is a union-like class}} 102 bool operator<=>(const D1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'D1' is a union-like class}} 103 }; 104 struct D2 { 105 union { 106 int a; 107 }; 108 109 bool operator==(const D2&) const; 110 bool operator!=(const D2&) const = default; 111 112 bool operator<=>(const D2&) const; 113 bool operator<(const D2&) const = default; 114 bool operator<=(const D2&) const = default; 115 bool operator>(const D2&) const = default; 116 bool operator>=(const D2&) const = default; 117 }; 118 119 union E1 { 120 bool operator==(const E1&) const = default; 121 bool operator!=(const E1&) const = default; 122 123 bool operator<=>(const E1&) const = default; 124 bool operator<(const E1&) const = default; 125 bool operator<=(const E1&) const = default; 126 bool operator>(const E1&) const = default; 127 bool operator>=(const E1&) const = default; 128 }; 129 union E2 { 130 bool operator==(const E2&) const = default; 131 bool operator!=(const E2&) const = default; 132 133 bool operator<=>(const E2&) const = default; 134 bool operator<(const E2&) const = default; 135 bool operator<=(const E2&) const = default; 136 bool operator>(const E2&) const = default; 137 bool operator>=(const E2&) const = default; 138 }; 139 140 struct F; 141 bool operator==(const F&, const F&); 142 bool operator!=(const F&, const F&); 143 bool operator<=>(const F&, const F&); 144 bool operator<(const F&, const F&); 145 struct F { 146 union { int a; }; 147 friend bool operator==(const F&, const F&) = default; // expected-error {{defaulting this equality comparison operator would delete it after its first declaration}} expected-note {{implicitly deleted because 'F' is a union-like class}} 148 friend bool operator!=(const F&, const F&) = default; 149 friend bool operator<=>(const F&, const F&) = default; // expected-error {{defaulting this three-way comparison operator would delete it after its first declaration}} expected-note {{implicitly deleted because 'F' is a union-like class}} 150 friend bool operator<(const F&, const F&) = default; 151 }; 152