[Flang] remove whole-archive option for AIX linker (#76039)
[llvm-project.git] / clang / test / CXX / class / class.compare / class.spaceship / p2.cpp
blob5648cea862a1bfd48eaf500ace9da6e243d451f0
1 // RUN: %clang_cc1 -std=c++2a -verify %s
3 namespace std {
4 class strong_ordering {
5 int n;
6 constexpr strong_ordering(int n) : n(n) {}
7 public:
8 static const strong_ordering less, equal, greater;
9 bool operator!=(int) { return n != 0; }
11 constexpr strong_ordering strong_ordering::less{-1},
12 strong_ordering::equal{0}, strong_ordering::greater{1};
14 class weak_ordering {
15 int n;
16 constexpr weak_ordering(int n) : n(n) {}
17 public:
18 constexpr weak_ordering(strong_ordering o);
19 static const weak_ordering less, equivalent, greater;
20 bool operator!=(int) { return n != 0; }
22 constexpr weak_ordering weak_ordering::less{-1},
23 weak_ordering::equivalent{0}, weak_ordering::greater{1};
25 class partial_ordering {
26 int n;
27 constexpr partial_ordering(int n) : n(n) {}
28 public:
29 constexpr partial_ordering(strong_ordering o);
30 constexpr partial_ordering(weak_ordering o);
31 static const partial_ordering less, equivalent, greater, unordered;
32 bool operator!=(int) { return n != 0; }
34 constexpr partial_ordering partial_ordering::less{-1},
35 partial_ordering::equivalent{0}, partial_ordering::greater{1},
36 partial_ordering::unordered{2};
39 namespace DeducedNotCat {
40 struct A {
41 A operator<=>(const A&) const; // expected-note {{selected 'operator<=>' for member 'a' declared here}}
43 struct B {
44 A a; // expected-note {{return type 'A' of three-way comparison for member 'a' is not a standard comparison category type}}
45 auto operator<=>(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
49 namespace DeducedVsSynthesized {
50 struct A {
51 bool operator==(const A&) const;
52 bool operator<(const A&) const;
54 struct B {
55 A a; // expected-note {{no viable three-way comparison function for member 'a'}}
56 auto operator<=>(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
60 namespace Deduction {
61 template<typename T> struct wrap {
62 T t;
63 friend auto operator<=>(const wrap&, const wrap&) = default;
66 using strong = wrap<int>;
67 using strong2 = wrap<int*>;
68 struct weak {
69 friend std::weak_ordering operator<=>(weak, weak);
71 using partial = wrap<float>;
73 template<typename ...T> struct A : T... {
74 friend auto operator<=>(const A&, const A&) = default;
77 template<typename Expected, typename ...Ts> void f() {
78 using T = Expected; // expected-note {{previous}}
79 using T = decltype(A<Ts...>() <=> A<Ts...>()); // expected-error {{different type}}
80 void(A<Ts...>() <=> A<Ts...>()); // trigger synthesis of body
83 template void f<std::strong_ordering>();
84 template void f<std::strong_ordering, strong>();
85 template void f<std::strong_ordering, strong, strong2>();
87 template void f<std::weak_ordering, weak>();
88 template void f<std::weak_ordering, weak, strong>();
89 template void f<std::weak_ordering, strong, weak>();
91 template void f<std::partial_ordering, partial>();
92 template void f<std::partial_ordering, weak, partial>();
93 template void f<std::partial_ordering, strong, partial>();
94 template void f<std::partial_ordering, partial, weak>();
95 template void f<std::partial_ordering, partial, strong>();
96 template void f<std::partial_ordering, weak, partial, strong>();
98 // Check that the above mechanism works.
99 template void f<std::strong_ordering, weak>(); // expected-note {{instantiation of}}
101 std::strong_ordering x = A<strong>() <=> A<strong>();
104 namespace PR44723 {
105 // Make sure we trigger return type deduction for a callee 'operator<=>'
106 // before inspecting its return type.
107 template<int> struct a {
108 friend constexpr auto operator<=>(a const &lhs, a const &rhs) {
109 return std::strong_ordering::equal;
112 struct b {
113 friend constexpr auto operator<=>(b const &, b const &) = default;
114 a<0> m_value;
116 std::strong_ordering cmp_b = b() <=> b();
118 struct c {
119 auto operator<=>(const c&) const&; // expected-note {{selected 'operator<=>' for base class 'c' declared here}}
121 struct d : c { // expected-note {{base class 'c' declared here}}
122 friend auto operator<=>(const d&, const d&) = default; // #d
123 // expected-error@#d {{return type of defaulted 'operator<=>' cannot be deduced because three-way comparison for base class 'c' has a deduced return type and is not yet defined}}
124 // expected-warning@#d {{implicitly deleted}}
125 // expected-note@#d {{replace 'default'}}
127 auto c::operator<=>(const c&) const& { // #c
128 return std::strong_ordering::equal;
130 // expected-error@+1 {{overload resolution selected deleted operator '<=>'}}
131 std::strong_ordering cmp_d = d() <=> d();
132 // expected-note@#c 2{{candidate}}
133 // expected-note@#d {{candidate function has been implicitly deleted}}
136 namespace BadDeducedType {
137 struct A {
138 // expected-error@+1 {{deduced return type for defaulted three-way comparison operator must be 'auto', not 'auto &'}}
139 friend auto &operator<=>(const A&, const A&) = default;
142 struct B {
143 // expected-error@+1 {{deduced return type for defaulted three-way comparison operator must be 'auto', not 'const auto'}}
144 friend const auto operator<=>(const B&, const B&) = default;
147 template<typename T> struct X {}; // expected-note {{here}}
148 struct C {
149 // expected-error@+1 {{deduction not allowed in function return type}}
150 friend X operator<=>(const C&, const C&) = default;
153 template<typename T> concept CmpCat = true;
154 struct D {
155 // expected-error@+1 {{deduced return type for defaulted three-way comparison operator must be 'auto', not 'CmpCat auto'}}
156 friend CmpCat auto operator<=>(const D&, const D&) = default;
160 namespace PR48856 {
161 struct A {
162 auto operator<=>(const A &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
163 void (*x)(); // expected-note {{because there is no viable three-way comparison function for member 'x'}}
166 struct B {
167 auto operator<=>(const B &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
168 void (B::*x)(); // expected-note {{because there is no viable three-way comparison function for member 'x'}}
171 struct C {
172 auto operator<=>(const C &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
173 int C::*x; // expected-note {{because there is no viable three-way comparison function for member 'x'}}
177 namespace PR50591 {
178 struct a1 {
179 operator int() const;
181 struct b1 {
182 auto operator<=>(b1 const &) const = default;
183 a1 f;
185 std::strong_ordering cmp_b1 = b1() <=> b1();
187 struct a2 {
188 operator float() const;
190 struct b2 {
191 auto operator<=>(b2 const &) const = default;
192 a2 f;
194 std::partial_ordering cmp_b2 = b2() <=> b2();
196 using fp = void (*)();
198 struct a3 {
199 operator fp() const;
201 struct b3 {
202 auto operator<=>(b3 const &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
203 a3 f; // expected-note {{because there is no viable three-way comparison function}}
206 struct a4 { // Test that function pointer conversion operator here is ignored for this overload resolution.
207 operator int() const;
208 operator fp() const;
210 struct b4 {
211 auto operator<=>(b4 const &) const = default;
212 a4 f;
214 std::strong_ordering cmp_b4 = b4() <=> b4();