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}} expected-note{{replace 'default'}}
8 bool operator<=>(const A1&) const = default; // expected-warning {{implicitly deleted}} expected-note 5{{deleted here}} expected-note{{replace 'default'}}
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 };
f(A1 a)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 }
f(A2 a)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}} expected-note{{replace 'default'}}
46 bool operator<(const A3 &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
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}} expected-note{{replace 'default'}}
57 bool operator<=>(const B1&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
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 }} expected-note{{replace 'default'}}
80 bool operator<=>(const C1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'C1' is a union }} expected-note{{replace 'default'}}
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}} expected-note{{replace 'default'}}
102 bool operator<=>(const D1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'D1' is a union-like class}} expected-note{{replace 'default'}}
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&); // expected-note {{previous declaration}}
143 bool operator<=>(const F&, const F&);
144 bool operator<(const F&, const F&); // expected-note {{previous declaration}}
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; // expected-error {{because it was already declared outside}}
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; // expected-error {{because it was already declared outside}}
151 };
152