85 lines · cpp
1// RUN: %clang_cc1 -std=c++2a -verify %s2 3namespace Rel {4 struct A {5 int n;6 constexpr int operator<=>(A a) const { return n - a.n; }7 friend bool operator<(const A&, const A&) = default;8 friend bool operator<=(const A&, const A&) = default;9 friend bool operator>(const A&, const A&) = default;10 friend bool operator>=(const A&, const A&) = default;11 };12 static_assert(A{0} < A{1});13 static_assert(A{1} < A{1}); // expected-error {{failed}}14 static_assert(A{0} <= A{1});15 static_assert(A{1} <= A{1});16 static_assert(A{2} <= A{1}); // expected-error {{failed}}17 static_assert(A{1} > A{0});18 static_assert(A{1} > A{1}); // expected-error {{failed}}19 static_assert(A{1} >= A{0});20 static_assert(A{1} >= A{1});21 static_assert(A{1} >= A{2}); // expected-error {{failed}}22 23 struct B {24 bool operator<=>(B) const = delete; // expected-note 4{{deleted here}} expected-note-re 8{{candidate {{.*}} deleted}}25 friend bool operator<(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note {{because it would invoke a deleted comparison}} expected-note-re {{candidate {{.*}} deleted}} expected-note{{replace 'default'}}26 friend bool operator<=(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note {{because it would invoke a deleted comparison}} expected-note-re {{candidate {{.*}} deleted}} expected-note{{replace 'default'}}27 friend bool operator>(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note {{because it would invoke a deleted comparison}} expected-note-re {{candidate {{.*}} deleted}} expected-note{{replace 'default'}}28 friend bool operator>=(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note {{because it would invoke a deleted comparison}} expected-note-re {{candidate {{.*}} deleted}} expected-note{{replace 'default'}}29 };30 bool b1 = B() < B(); // expected-error {{deleted}}31 bool b2 = B() <= B(); // expected-error {{deleted}}32 bool b3 = B() > B(); // expected-error {{deleted}}33 bool b4 = B() >= B(); // expected-error {{deleted}}34 35 struct C {36 friend bool operator<=>(const C&, const C&);37 friend bool operator<(const C&, const C&); // expected-note {{because this non-rewritten comparison function would be the best match}}38 39 bool operator<(const C&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}40 bool operator>(const C&) const = default; // OK41 };42}43 44// Under P2002R0, operator!= follows these rules too.45namespace NotEqual {46 struct A {47 int n;48 constexpr bool operator==(A a) const { return n == a.n; }49 friend bool operator!=(const A&, const A&) = default;50 };51 static_assert(A{1} != A{2});52 static_assert(A{1} != A{1}); // expected-error {{failed}}53 54 struct B {55 bool operator==(B) const = delete; // expected-note {{deleted here}} expected-note-re 2{{candidate {{.*}} deleted}}56 friend bool operator!=(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note {{because it would invoke a deleted comparison}} expected-note-re {{candidate {{.*}} deleted}} expected-note{{replace 'default'}}57 };58 bool b = B() != B(); // expected-error {{deleted}}59 60 struct C {61 friend bool operator==(const C&, const C&);62 friend bool operator!=(const C&, const C&); // expected-note {{because this non-rewritten comparison function would be the best match}}63 64 bool operator!=(const C&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}65 };66 67 // Ensure we don't go into an infinite loop diagnosing this: the first function68 // is deleted because it calls the second function, which is deleted because it69 // calls the first.70 struct Evil {71 friend bool operator!=(const Evil&, const Evil&) = default; // expected-warning {{implicitly deleted}} expected-note {{would be the best match}} expected-note{{replace 'default'}}72 bool operator!=(const Evil&) const = default; // expected-warning {{implicitly deleted}} expected-note {{would be the best match}} expected-note{{replace 'default'}}73 };74}75 76namespace Access {77 class A {78 int operator<=>(A) const; // expected-note {{private}}79 };80 struct B : A {81 friend bool operator<(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}82 // expected-note@-1 {{defaulted 'operator<' is implicitly deleted because it would invoke a private 'operator<=>' member of 'Access::A'}}83 };84}85