[flang][cuda] Adapt ExternalNameConversion to work in gpu module (#117039)
[llvm-project.git] / clang / test / AST / ByteCode / spaceship.cpp
blob7495b893772e80daad8a881cf4ecf27d6b03b562
1 // RUN: %clang_cc1 -std=c++2a -verify=both,ref %s -fcxx-exceptions
2 // RUN: %clang_cc1 -std=c++2a -verify=both,expected %s -fcxx-exceptions -fexperimental-new-constant-interpreter
4 namespace std {
5 struct strong_ordering { // both-note 6{{candidate}}
6 int n;
7 constexpr operator int() const { return n; }
8 static const strong_ordering less, equal, greater;
9 };
10 constexpr strong_ordering strong_ordering::less{-1},
11 strong_ordering::equal{0}, strong_ordering::greater{1};
13 struct weak_ordering {
14 int n;
15 constexpr weak_ordering(int n) : n(n) {}
16 constexpr weak_ordering(strong_ordering o) : n(o.n) {}
17 constexpr operator int() const { return n; }
18 static const weak_ordering less, equivalent, greater;
20 constexpr weak_ordering weak_ordering::less{-1},
21 weak_ordering::equivalent{0}, weak_ordering::greater{1};
23 struct partial_ordering {
24 double d;
25 constexpr partial_ordering(double d) : d(d) {}
26 constexpr partial_ordering(strong_ordering o) : d(o.n) {}
27 constexpr partial_ordering(weak_ordering o) : d(o.n) {}
28 constexpr operator double() const { return d; }
29 static const partial_ordering less, equivalent, greater, unordered;
31 constexpr partial_ordering partial_ordering::less{-1},
32 partial_ordering::equivalent{0}, partial_ordering::greater{1},
33 partial_ordering::unordered{__builtin_nan("")};
35 static_assert(!(partial_ordering::unordered < 0));
36 static_assert(!(partial_ordering::unordered == 0));
37 static_assert(!(partial_ordering::unordered > 0));
40 namespace Deletedness {
41 struct A {
42 std::strong_ordering operator<=>(const A&) const;
44 struct B {
45 bool operator==(const B&) const;
46 bool operator<(const B&) const;
48 struct C {
49 std::strong_ordering operator<=>(const C&) const = delete; // both-note 2{{deleted}}
51 struct D1 {
52 bool operator==(const D1&) const;
53 std::strong_ordering operator<=>(int) const; // both-note 2{{function not viable}} both-note 2{{function (with reversed parameter order) not viable}}
54 bool operator<(int) const; // both-note 2{{function not viable}}
56 struct D2 {
57 bool operator<(const D2&) const;
58 std::strong_ordering operator<=>(int) const; // both-note 2{{function not viable}} both-note 2{{function (with reversed parameter order) not viable}}
59 bool operator==(int) const; // both-note 2{{function not viable}}
61 struct E {
62 bool operator==(const E&) const;
63 bool operator<(const E&) const = delete; // both-note 2{{deleted}}
65 struct F {
66 std::strong_ordering operator<=>(const F&) const; // both-note 2{{candidate}}
67 std::strong_ordering operator<=>(F) const; // both-note 2{{candidate}}
69 struct G1 {
70 bool operator==(const G1&) const;
71 void operator<(const G1&) const;
73 struct G2 {
74 void operator==(const G2&) const;
75 bool operator<(const G2&) const;
77 struct H {
78 void operator<=>(const H&) const;
81 // both-note@#base {{deleted comparison function for base class 'C'}}
82 // both-note@#base {{no viable three-way comparison function for base class 'D1'}}
83 // both-note@#base {{three-way comparison cannot be synthesized because there is no viable function for '<' comparison}}
84 // both-note@#base {{no viable 'operator==' for base class 'D2'}}
85 // both-note@#base {{three-way comparison cannot be synthesized because there is no viable function for '==' comparison}}
86 // both-note@#base {{deleted comparison function for base class 'E'}}
87 // both-note@#base {{implied comparison for base class 'F' is ambiguous}}
88 template<typename T> struct Cmp : T { // #base
89 std::strong_ordering operator<=>(const Cmp&) const = default; // #cmp both-note 5{{here}}
92 void use(...);
93 void f() {
94 use(
95 Cmp<A>() <=> Cmp<A>(),
96 Cmp<B>() <=> Cmp<B>(),
97 Cmp<C>() <=> Cmp<C>(), // both-error {{deleted}}
98 Cmp<D1>() <=> Cmp<D1>(), // both-error {{deleted}}
99 Cmp<D2>() <=> Cmp<D2>(), // both-error {{deleted}}
100 Cmp<E>() <=> Cmp<E>(), // both-error {{deleted}}
101 Cmp<F>() <=> Cmp<F>(), // both-error {{deleted}}
102 // FIXME: The following three errors are not very good.
103 // both-error@#cmp {{value of type 'void' is not contextually convertible to 'bool'}}
104 Cmp<G1>() <=> Cmp<G1>(), // both-note-re {{in defaulted three-way comparison operator for '{{.*}}Cmp<{{.*}}G1>' first required here}}j
105 // both-error@#cmp {{value of type 'void' is not contextually convertible to 'bool'}}
106 Cmp<G2>() <=> Cmp<G2>(), // both-note-re {{in defaulted three-way comparison operator for '{{.*}}Cmp<{{.*}}G2>' first required here}}j
107 // both-error@#cmp {{no matching conversion for static_cast from 'void' to 'std::strong_ordering'}}
108 Cmp<H>() <=> Cmp<H>(), // both-note-re {{in defaulted three-way comparison operator for '{{.*}}Cmp<{{.*}}H>' first required here}}j
113 // both-note@#arr {{deleted comparison function for member 'arr'}}
114 // both-note@#arr {{no viable three-way comparison function for member 'arr'}}
115 // both-note@#arr {{three-way comparison cannot be synthesized because there is no viable function for '<' comparison}}
116 // both-note@#arr {{no viable 'operator==' for member 'arr'}}
117 // both-note@#arr {{three-way comparison cannot be synthesized because there is no viable function for '==' comparison}}
118 // both-note@#arr {{deleted comparison function for member 'arr'}}
119 // both-note@#arr {{implied comparison for member 'arr' is ambiguous}}
120 template<typename T> struct CmpArray {
121 T arr[3]; // #arr
122 std::strong_ordering operator<=>(const CmpArray&) const = default; // #cmparray both-note 5{{here}}
124 void g() {
125 use(
126 CmpArray<A>() <=> CmpArray<A>(),
127 CmpArray<B>() <=> CmpArray<B>(),
128 CmpArray<C>() <=> CmpArray<C>(), // both-error {{deleted}}
129 CmpArray<D1>() <=> CmpArray<D1>(), // both-error {{deleted}}
130 CmpArray<D2>() <=> CmpArray<D2>(), // both-error {{deleted}}
131 CmpArray<E>() <=> CmpArray<E>(), // both-error {{deleted}}
132 CmpArray<F>() <=> CmpArray<F>(), // both-error {{deleted}}
133 // FIXME: The following three errors are not very good.
134 // both-error@#cmparray {{value of type 'void' is not contextually convertible to 'bool'}}
135 CmpArray<G1>() <=> CmpArray<G1>(), // both-note-re {{in defaulted three-way comparison operator for '{{.*}}CmpArray<{{.*}}G1>' first required here}}j
136 // both-error@#cmparray {{value of type 'void' is not contextually convertible to 'bool'}}
137 CmpArray<G2>() <=> CmpArray<G2>(), // both-note-re {{in defaulted three-way comparison operator for '{{.*}}CmpArray<{{.*}}G2>' first required here}}j
138 // both-error@#cmparray {{no matching conversion for static_cast from 'void' to 'std::strong_ordering'}}
139 CmpArray<H>() <=> CmpArray<H>(), // both-note-re {{in defaulted three-way comparison operator for '{{.*}}CmpArray<{{.*}}H>' first required here}}j
145 namespace Access {
146 class A {
147 std::strong_ordering operator<=>(const A &) const; // both-note {{here}}
148 public:
149 bool operator==(const A &) const;
150 bool operator<(const A &) const;
152 struct B {
153 A a; // both-note {{would invoke a private 'operator<=>'}}
154 friend std::strong_ordering operator<=>(const B &, const B &) = default; // both-warning {{deleted}} both-note{{replace 'default'}}
157 class C {
158 std::strong_ordering operator<=>(const C &); // not viable (not const)
159 bool operator==(const C &) const; // both-note {{here}}
160 bool operator<(const C &) const;
162 struct D {
163 C c; // both-note {{would invoke a private 'operator=='}}
164 friend std::strong_ordering operator<=>(const D &, const D &) = default; // both-warning {{deleted}} both-note{{replace 'default'}}
168 namespace Synthesis {
169 enum Result { False, True, Mu };
171 constexpr bool toBool(Result R) {
172 if (R == Mu) throw "should not ask this question";
173 return R == True;
176 struct Val {
177 Result equal, less;
178 constexpr bool operator==(const Val&) const { return toBool(equal); }
179 constexpr bool operator<(const Val&) const { return toBool(less); }
182 template<typename T> struct Cmp {
183 Val val;
184 friend T operator<=>(const Cmp&, const Cmp&) = default; // both-note {{deleted}}
187 template<typename T> constexpr auto cmp(Result equal, Result less = Mu, Result reverse_less = Mu) {
188 return Cmp<T>{equal, less} <=> Cmp<T>{Mu, reverse_less};
191 static_assert(cmp<std::strong_ordering>(True) == 0);
192 static_assert(cmp<std::strong_ordering>(False, True) < 0);
193 static_assert(cmp<std::strong_ordering>(False, False) > 0);
195 static_assert(cmp<std::weak_ordering>(True) == 0);
196 static_assert(cmp<std::weak_ordering>(False, True) < 0);
197 static_assert(cmp<std::weak_ordering>(False, False) > 0);
199 static_assert(cmp<std::partial_ordering>(True) == 0);
200 static_assert(cmp<std::partial_ordering>(False, True) < 0);
201 static_assert(cmp<std::partial_ordering>(False, False, True) > 0);
202 static_assert(!(cmp<std::partial_ordering>(False, False, False) > 0));
203 static_assert(!(cmp<std::partial_ordering>(False, False, False) == 0));
204 static_assert(!(cmp<std::partial_ordering>(False, False, False) < 0));
206 // No synthesis is performed for a custom return type, even if it can be
207 // converted from a standard ordering.
208 struct custom_ordering {
209 custom_ordering(std::strong_ordering o);
211 void f(Cmp<custom_ordering> c) {
212 c <=> c; // both-error {{deleted}}
216 namespace Preference {
217 struct A {
218 A(const A&) = delete; // both-note {{deleted}}
219 // "usable" candidate that can't actually be called
220 friend void operator<=>(A, A); // both-note {{passing}}
221 // Callable candidates for synthesis not considered.
222 friend bool operator==(A, A);
223 friend bool operator<(A, A);
226 struct B {
227 B();
228 A a;
229 std::strong_ordering operator<=>(const B&) const = default; // both-error {{call to deleted constructor of 'A'}}
231 bool x = B() < B(); // both-note {{in defaulted three-way comparison operator for 'B' first required here}}