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 Smithvoid 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 Smithvoid 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