Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CXX / class / class.compare / class.compare.default / p4.cpp
blob02cdd7f85aebfa58cb0b78d586941dbf65374c39
1 // RUN: %clang_cc1 -std=c++2a -verify %s
2 // RUN: %clang_cc1 -std=c++2a -Wc++23-default-comp-relaxed-constexpr -verify=expected,extension %s
4 // This test is for [class.compare.default]p3 as modified and renumbered to p4
5 // by P2002R0.
6 // Also covers modifications made by P2448R2 and extension warnings
8 namespace std {
9 struct strong_ordering {
10 int n;
11 constexpr operator int() const { return n; }
12 static const strong_ordering less, equal, greater;
14 constexpr strong_ordering strong_ordering::less = {-1};
15 constexpr strong_ordering strong_ordering::equal = {0};
16 constexpr strong_ordering strong_ordering::greater = {1};
19 namespace N {
20 struct A {
21 friend constexpr std::strong_ordering operator<=>(const A&, const A&) = default;
24 constexpr bool (*test_a_not_found)(const A&, const A&) = &operator==; // expected-error {{undeclared}}
26 constexpr bool operator==(const A&, const A&) noexcept;
27 constexpr bool (*test_a)(const A&, const A&) noexcept = &operator==;
28 static_assert((*test_a)(A(), A()));
31 struct B1 {
32 virtual std::strong_ordering operator<=>(const B1&) const = default;
34 bool (B1::*test_b)(const B1&) const = &B1::operator==;
36 struct C1 : B1 {
37 // OK, B1::operator== is virtual.
38 bool operator==(const B1&) const override;
41 struct B2 {
42 std::strong_ordering operator<=>(const B2&) const = default;
45 struct C2 : B2 {
46 bool operator==(const B2&) const override; // expected-error {{only virtual member functions}}
49 struct D {
50 std::strong_ordering operator<=>(const D&) const;
51 virtual std::strong_ordering operator<=>(const struct E&) const = 0;
53 struct E : D {
54 // expected-error@+2 {{only virtual member functions}}
55 // expected-note@+1 {{while declaring the corresponding implicit 'operator==' for this defaulted 'operator<=>'}}
56 std::strong_ordering operator<=>(const E&) const override = default;
59 struct F {
60 [[deprecated("oh no")]] std::strong_ordering operator<=>(const F&) const = default; // expected-note 4{{deprecated}}
62 void use_f(F f) {
63 void(f <=> f); // expected-warning {{oh no}}
64 void(f < f); // expected-warning {{oh no}}
65 void(f == f); // expected-warning {{oh no}}
66 void(f != f); // expected-warning {{oh no}}
69 class G {
70 // expected-note@+2 {{implicitly declared private here}}
71 // expected-note-re@+1 {{{{^}}declared private here}}
72 std::strong_ordering operator<=>(const G&) const = default;
73 public:
75 void use_g(G g) {
76 void(g <=> g); // expected-error {{private}}
77 void(g == g); // expected-error {{private}}
80 struct H {
81 bool operator==(const H&) const; // extension-note {{non-constexpr comparison function declared here}}
82 constexpr std::strong_ordering operator<=>(const H&) const { return std::strong_ordering::equal; }
85 struct I {
86 H h; // extension-note {{non-constexpr comparison function would be used to compare member 'h'}}
87 constexpr std::strong_ordering operator<=>(const I&) const = default; // extension-warning {{implicit 'operator==' invokes a non-constexpr comparison function is a C++23 extension}}
90 struct J {
91 std::strong_ordering operator<=>(const J&) const & = default; // expected-note {{candidate function (the implicit 'operator==' for this 'operator<=>)'}}
92 friend std::strong_ordering operator<=>(const J&, const J&) = default; // expected-note {{candidate function (the implicit 'operator==' for this 'operator<=>)'}}
94 void use_j(J j) {
95 void(j == j); // expected-error {{ambiguous}}
98 namespace DeleteAfterFirstDecl {
99 bool operator==(const struct Q&, const struct Q&);
100 struct Q {
101 struct X {
102 friend std::strong_ordering operator<=>(const X&, const X&);
103 } x; // expected-note {{no viable 'operator=='}}
104 // expected-error@+1 {{defaulting the corresponding implicit 'operator==' for this defaulted 'operator<=>' would delete it after its first declaration}}
105 friend std::strong_ordering operator<=>(const Q&, const Q&) = default;
109 // Note, substitution here results in the second parameter of 'operator=='
110 // referring to the first parameter of 'operator==', not to the first parameter
111 // of 'operator<=>'.
112 // FIXME: Find a case where this matters (attribute enable_if?).
113 struct K {
114 friend std::strong_ordering operator<=>(const K &k, decltype(k)) = default;
116 bool test_k = K() == K();
118 namespace NoInjectionIfOperatorEqualsDeclared {
119 struct A {
120 void operator==(int); // expected-note 2{{not viable}}
121 std::strong_ordering operator<=>(const A&) const = default;
123 bool test_a = A() == A(); // expected-error {{invalid operands}}
125 struct B {
126 friend void operator==(int, struct Q); // expected-note 2{{not viable}}
127 std::strong_ordering operator<=>(const B&) const = default;
129 bool test_b = B() == B(); // expected-error {{invalid operands}}
131 struct C {
132 void operator==(int); // expected-note 2{{not viable}}
133 friend std::strong_ordering operator<=>(const C&, const C&) = default;
135 bool test_c = C() == C(); // expected-error {{invalid operands}}
137 struct D {
138 void f() {
139 void operator==(const D&, int);
141 struct X {
142 friend void operator==(const D&, int);
144 friend std::strong_ordering operator<=>(const D&, const D&) = default;
146 bool test_d = D() == D();
149 namespace GH61238 {
150 template <typename A> struct my_struct {
151 A value; // extension-note {{non-constexpr comparison function would be used to compare member 'value'}}
153 constexpr friend bool operator==(const my_struct &, const my_struct &) noexcept = default; // extension-warning {{declared constexpr but invokes a non-constexpr comparison function is a C++23 extension}}
156 struct non_constexpr_type {
157 friend bool operator==(non_constexpr_type, non_constexpr_type) noexcept { // extension-note {{non-constexpr comparison function declared here}}
158 return false;
162 my_struct<non_constexpr_type> obj; // extension-note {{in instantiation of template class 'GH61238::my_struct<GH61238::non_constexpr_type>' requested here}}