xref: /llvm-project/clang/test/CXX/class/class.compare/class.compare.default/p2.cpp (revision 6a763343e29f339cf3a9d282a309589174c74f09)
1a4facd35SRichard Smith // RUN: %clang_cc1 -std=c++2a -verify %s
2a4facd35SRichard Smith 
35253d913SRichard Smith struct A1 {
4a4facd35SRichard Smith   int x;
55253d913SRichard Smith   int &y; // expected-note 9{{because class 'A1' has a reference member}}
6a4facd35SRichard Smith 
71376c739SNathan James   bool operator==(const A1&) const = default; // expected-warning {{implicitly deleted}} expected-note 2{{deleted here}} expected-note{{replace 'default'}}
81376c739SNathan James   bool operator<=>(const A1&) const = default; // expected-warning {{implicitly deleted}} expected-note 5{{deleted here}} expected-note{{replace 'default'}}
9a4facd35SRichard Smith };
105253d913SRichard Smith struct A2 {
115253d913SRichard Smith   int x;
125253d913SRichard Smith   int &y;
13a4facd35SRichard Smith 
145253d913SRichard Smith   bool operator==(const A2&) const;
155253d913SRichard Smith   bool operator!=(const A2&) const = default;
165253d913SRichard Smith 
17cafc7416SRichard Smith   int operator<=>(const A2&) const;
185253d913SRichard Smith   bool operator<(const A2&) const = default;
195253d913SRichard Smith   bool operator<=(const A2&) const = default;
205253d913SRichard Smith   bool operator>(const A2&) const = default;
215253d913SRichard Smith   bool operator>=(const A2&) const = default;
225253d913SRichard Smith };
f(A1 a)235253d913SRichard Smith void f(A1 a) {
245253d913SRichard Smith   void(a == a); // expected-error {{deleted}}
255253d913SRichard Smith   void(a != a); // expected-error {{deleted}}
265253d913SRichard Smith   void(a <=> a); // expected-error {{deleted}}
275253d913SRichard Smith   void(a < a); // expected-error {{deleted}}
285253d913SRichard Smith   void(a <= a); // expected-error {{deleted}}
295253d913SRichard Smith   void(a > a); // expected-error {{deleted}}
305253d913SRichard Smith   void(a >= a); // expected-error {{deleted}}
315253d913SRichard Smith }
f(A2 a)325253d913SRichard Smith void f(A2 a) {
335253d913SRichard Smith   void(a == a);
345253d913SRichard Smith   void(a != a);
355253d913SRichard Smith   void(a <=> a);
365253d913SRichard Smith   void(a < a);
375253d913SRichard Smith   void(a <= a);
385253d913SRichard Smith   void(a > a);
395253d913SRichard Smith   void(a >= a);
405253d913SRichard Smith }
415253d913SRichard Smith 
424a8530fcSMatheus Izvekov struct A3 {
434a8530fcSMatheus Izvekov   int &x; // expected-note {{because class 'A3' has a reference member}}
444a8530fcSMatheus Izvekov 
451376c739SNathan James   bool operator==(const A3 &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
461376c739SNathan James   bool operator<(const A3 &) const = default;  // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
47c9fd92d5SMatheus Izvekov   // expected-note@-1 {{because there is no viable three-way comparison function for 'A3'}}
484a8530fcSMatheus Izvekov };
494a8530fcSMatheus Izvekov 
505253d913SRichard Smith struct B1 {
51a4facd35SRichard Smith   struct {
52a4facd35SRichard Smith     int x;
535253d913SRichard Smith     int &y; // expected-note 2{{because class 'B1' has a reference member}}
54a4facd35SRichard Smith   };
55a4facd35SRichard Smith 
561376c739SNathan James   bool operator==(const B1&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
571376c739SNathan James   bool operator<=>(const B1&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
58a4facd35SRichard Smith };
59a4facd35SRichard Smith 
605253d913SRichard Smith struct B2 {
615253d913SRichard Smith   struct {
625253d913SRichard Smith     int x;
635253d913SRichard Smith     int &y;
645253d913SRichard Smith   };
655253d913SRichard Smith 
665253d913SRichard Smith   bool operator==(const B2&) const;
675253d913SRichard Smith   bool operator!=(const B2&) const = default;
685253d913SRichard Smith 
695253d913SRichard Smith   bool operator<=>(const B2&) const;
705253d913SRichard Smith   bool operator<(const B2&) const = default;
715253d913SRichard Smith   bool operator<=(const B2&) const = default;
725253d913SRichard Smith   bool operator>(const B2&) const = default;
735253d913SRichard Smith   bool operator>=(const B2&) const = default;
745253d913SRichard Smith };
755253d913SRichard Smith 
765253d913SRichard Smith union C1 {
77a4facd35SRichard Smith   int a;
78a4facd35SRichard Smith 
791376c739SNathan James   bool operator==(const C1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'C1' is a union }} expected-note{{replace 'default'}}
801376c739SNathan James   bool operator<=>(const C1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'C1' is a union }} expected-note{{replace 'default'}}
81a4facd35SRichard Smith };
82a4facd35SRichard Smith 
835253d913SRichard Smith union C2 {
845253d913SRichard Smith   int a;
855253d913SRichard Smith 
865253d913SRichard Smith   bool operator==(const C2&) const;
875253d913SRichard Smith   bool operator!=(const C2&) const = default;
885253d913SRichard Smith 
895253d913SRichard Smith   bool operator<=>(const C2&) const;
905253d913SRichard Smith   bool operator<(const C2&) const = default;
915253d913SRichard Smith   bool operator<=(const C2&) const = default;
925253d913SRichard Smith   bool operator>(const C2&) const = default;
935253d913SRichard Smith   bool operator>=(const C2&) const = default;
945253d913SRichard Smith };
955253d913SRichard Smith 
965253d913SRichard Smith struct D1 {
97a4facd35SRichard Smith   union {
98a4facd35SRichard Smith     int a;
99a4facd35SRichard Smith   };
100a4facd35SRichard Smith 
1011376c739SNathan James   bool operator==(const D1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'D1' is a union-like class}} expected-note{{replace 'default'}}
1021376c739SNathan James   bool operator<=>(const D1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'D1' is a union-like class}} expected-note{{replace 'default'}}
1035253d913SRichard Smith };
1045253d913SRichard Smith struct D2 {
1055253d913SRichard Smith   union {
1065253d913SRichard Smith     int a;
107a4facd35SRichard Smith   };
108a4facd35SRichard Smith 
1095253d913SRichard Smith   bool operator==(const D2&) const;
1105253d913SRichard Smith   bool operator!=(const D2&) const = default;
111a4facd35SRichard Smith 
1125253d913SRichard Smith   bool operator<=>(const D2&) const;
1135253d913SRichard Smith   bool operator<(const D2&) const = default;
1145253d913SRichard Smith   bool operator<=(const D2&) const = default;
1155253d913SRichard Smith   bool operator>(const D2&) const = default;
1165253d913SRichard Smith   bool operator>=(const D2&) const = default;
1175253d913SRichard Smith };
1185253d913SRichard Smith 
1195253d913SRichard Smith union E1 {
1205253d913SRichard Smith   bool operator==(const E1&) const = default;
1215253d913SRichard Smith   bool operator!=(const E1&) const = default;
1225253d913SRichard Smith 
1235253d913SRichard Smith   bool operator<=>(const E1&) const = default;
1245253d913SRichard Smith   bool operator<(const E1&) const = default;
1255253d913SRichard Smith   bool operator<=(const E1&) const = default;
1265253d913SRichard Smith   bool operator>(const E1&) const = default;
1275253d913SRichard Smith   bool operator>=(const E1&) const = default;
1285253d913SRichard Smith };
1295253d913SRichard Smith union E2 {
1305253d913SRichard Smith   bool operator==(const E2&) const = default;
1315253d913SRichard Smith   bool operator!=(const E2&) const = default;
1325253d913SRichard Smith 
1335253d913SRichard Smith   bool operator<=>(const E2&) const = default;
1345253d913SRichard Smith   bool operator<(const E2&) const = default;
1355253d913SRichard Smith   bool operator<=(const E2&) const = default;
1365253d913SRichard Smith   bool operator>(const E2&) const = default;
1375253d913SRichard Smith   bool operator>=(const E2&) const = default;
1385253d913SRichard Smith };
1395253d913SRichard Smith 
1405253d913SRichard Smith struct F;
1415253d913SRichard Smith bool operator==(const F&, const F&);
142*6a763343SRoy Jacobson bool operator!=(const F&, const F&); // expected-note {{previous declaration}}
1435253d913SRichard Smith bool operator<=>(const F&, const F&);
144*6a763343SRoy Jacobson bool operator<(const F&, const F&); // expected-note {{previous declaration}}
1455253d913SRichard Smith struct F {
1465253d913SRichard Smith   union { int a; };
1475253d913SRichard Smith   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*6a763343SRoy Jacobson   friend bool operator!=(const F&, const F&) = default; // expected-error {{because it was already declared outside}}
1495253d913SRichard Smith   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*6a763343SRoy Jacobson   friend bool operator<(const F&, const F&) = default; // expected-error {{because it was already declared outside}}
151a4facd35SRichard Smith };
152