1 // RUN: %clang_cc1 -fsyntax-only -fshow-overloads=best -verify -triple x86_64-linux-gnu %s
2
3 struct yes;
4 struct no;
5
6 struct Short {
7 operator short();
8 };
9
10 struct Long {
11 operator long();
12 };
13
14 enum E1 { };
15 struct Enum1 {
16 operator E1();
17 };
18
19 enum E2 { };
20 struct Enum2 {
21 operator E2();
22 };
23
24
25 struct X {
26 void f();
27 };
28
29 typedef void (X::*pmf)();
30 struct Xpmf {
31 operator pmf();
32 };
33
34 yes& islong(long);
35 yes& islong(unsigned long); // FIXME: shouldn't be needed
36 no& islong(int);
37
f(Short s,Long l,Enum1 e1,Enum2 e2,Xpmf pmf)38 void f(Short s, Long l, Enum1 e1, Enum2 e2, Xpmf pmf) {
39 // C++ [over.built]p8
40 int i1 = +e1;
41 int i2 = -e2;
42
43 // C++ [over.built]p10:
44 int i3 = ~s;
45 bool b1 = !s;
46
47 // C++ [over.built]p12
48 (void)static_cast<yes&>(islong(s + l));
49 (void)static_cast<no&>(islong(s + s));
50
51 // C++ [over.built]p16
52 (void)(pmf == &X::f);
53 (void)(pmf == 0);
54
55 // C++ [over.built]p17
56 (void)static_cast<yes&>(islong(s % l));
57 (void)static_cast<yes&>(islong(l << s));
58 (void)static_cast<no&>(islong(s << l));
59 (void)static_cast<yes&>(islong(e1 % l));
60 // FIXME: should pass (void)static_cast<no&>(islong(e1 % e2));
61 }
62
63 struct ShortRef { // expected-note{{candidate function (the implicit copy assignment operator)}}
64 operator short&();
65 };
66
67 struct LongRef {
68 operator volatile long&();
69 };
70
71 struct XpmfRef { // expected-note{{candidate function (the implicit copy assignment operator)}}
72 operator pmf&();
73 };
74
75 struct E2Ref {
76 operator E2&();
77 };
78
g(ShortRef sr,LongRef lr,E2Ref e2_ref,XpmfRef pmf_ref)79 void g(ShortRef sr, LongRef lr, E2Ref e2_ref, XpmfRef pmf_ref) {
80 // C++ [over.built]p3
81 short s1 = sr++;
82
83 // C++ [over.built]p3
84 long l1 = lr--;
85
86 // C++ [over.built]p18
87 short& sr1 = (sr *= lr);
88 volatile long& lr1 = (lr *= sr);
89
90 // C++ [over.built]p20:
91 E2 e2r2;
92 e2r2 = e2_ref;
93
94 pmf &pmr = (pmf_ref = &X::f); // expected-error{{no viable overloaded '='}}
95 pmf pmr2;
96 pmr2 = pmf_ref;
97
98 // C++ [over.built]p22
99 short& sr2 = (sr %= lr);
100 volatile long& lr2 = (lr <<= sr);
101
102 bool b1 = (sr && lr) || (sr || lr);
103 }
104
105 struct VolatileIntPtr {
106 operator int volatile *();
107 };
108
109 struct ConstIntPtr {
110 operator int const *();
111 };
112
113 struct VolatileIntPtrRef {
114 operator int volatile *&();
115 };
116
117 struct ConstIntPtrRef {
118 operator int const *&();
119 };
120
test_with_ptrs(VolatileIntPtr vip,ConstIntPtr cip,ShortRef sr,VolatileIntPtrRef vipr,ConstIntPtrRef cipr)121 void test_with_ptrs(VolatileIntPtr vip, ConstIntPtr cip, ShortRef sr,
122 VolatileIntPtrRef vipr, ConstIntPtrRef cipr) {
123 const int& cir1 = cip[sr];
124 const int& cir2 = sr[cip];
125 volatile int& vir1 = vip[sr];
126 volatile int& vir2 = sr[vip];
127 bool b1 = (vip == cip);
128 long p1 = vip - cip;
129
130 // C++ [over.built]p5:
131 int volatile *vip1 = vipr++;
132 int const *cip1 = cipr++;
133 int volatile *&vipr1 = ++vipr;
134 int const *&cipr1 = --cipr;
135
136 // C++ [over.built]p6:
137 int volatile &ivr = *vip;
138
139 // C++ [over.built]p8:
140 int volatile *vip2 = +vip;
141 int i1 = +sr;
142 int i2 = -sr;
143
144 // C++ [over.built]p13:
145 int volatile &ivr2 = vip[17];
146 int const &icr2 = 17[cip];
147 }
148
149 // C++ [over.match.open]p4
150
test_assign_restrictions(ShortRef & sr)151 void test_assign_restrictions(ShortRef& sr) {
152 sr = (short)0; // expected-error{{no viable overloaded '='}}
153 }
154
155 struct Base { };
156 struct Derived1 : Base { };
157 struct Derived2 : Base { };
158
159 template<typename T>
160 struct ConvertibleToPtrOf {
161 operator T*();
162 };
163
test_with_base_ptrs(ConvertibleToPtrOf<Derived1> d1,ConvertibleToPtrOf<Derived2> d2)164 bool test_with_base_ptrs(ConvertibleToPtrOf<Derived1> d1,
165 ConvertibleToPtrOf<Derived2> d2) {
166 return d1 == d2; // expected-error{{invalid operands}}
167 }
168
169 // DR425
170 struct A {
171 template< typename T > operator T() const;
172 };
173
test_dr425(A a)174 void test_dr425(A a) {
175 // FIXME: lots of candidates here!
176 (void)(1.0f * a); // expected-error{{ambiguous}} \
177 // expected-note 4{{candidate}} \
178 // expected-note {{remaining 117 candidates omitted; pass -fshow-overloads=all to show them}}
179 }
180
181 // pr5432
182 enum e {X};
183
184 const int a[][2] = {{1}};
185
test_pr5432()186 int test_pr5432() {
187 return a[X][X];
188 }
189
f()190 void f() {
191 (void)__extension__(A());
192 }
193
194 namespace PR7319 {
195 typedef enum { Enum1, Enum2, Enum3 } MyEnum;
196
197 template<typename X> bool operator>(const X &inX1, const X &inX2);
198
f()199 void f() {
200 MyEnum e1, e2;
201 if (e1 > e2) {}
202 }
203 }
204
205 namespace PR8477 {
206 struct Foo {
207 operator bool();
208 operator const char *();
209 };
210
doit()211 bool doit() {
212 Foo foo;
213 long long zero = 0;
214 (void)(foo + zero);
215 (void)(foo - zero);
216 (void)(zero + foo);
217 (void)(zero[foo]);
218 (void)(foo - foo); // expected-error{{use of overloaded operator '-' is ambiguous}} \
219 // expected-note 4{{built-in candidate operator-}} \
220 // expected-note{{candidates omitted}}
221 return foo[zero] == zero;
222 }
223 }
224
225 namespace PR7851 {
226 struct X {
227 operator const void *() const;
228 operator void *();
229
230 operator const unsigned *() const;
231 operator unsigned *();
232 };
233
f()234 void f() {
235 X x;
236 x[0] = 1;
237 *x = 0;
238 (void)(x - x);
239 }
240 }
241
242 namespace PR12854 {
243 enum { size = 1 };
plus_equals()244 void plus_equals() {
245 int* __restrict py;
246 py += size;
247 }
248
249 struct RestrictInt {
250 operator int* __restrict &();
251 };
252
user_conversions(RestrictInt ri)253 void user_conversions(RestrictInt ri) {
254 ++ri;
255 --ri;
256 ri++;
257 ri--;
258 }
259 }
260
261 namespace PR12964 {
262 struct X { operator __int128() const; } x;
263 bool a = x == __int128(0);
264 bool b = x == 0;
265
266 struct Y { operator unsigned __int128() const; } y;
267 bool c = y == __int128(0);
268 bool d = y == 0;
269
270 bool e = x == y;
271 }
272