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 
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 
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 
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 
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 
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 
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 
186 int test_pr5432() {
187   return a[X][X];
188 }
189 
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 
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 
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 
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 };
244   void plus_equals() {
245     int* __restrict py;
246     py += size;
247   }
248 
249   struct RestrictInt {
250     operator int* __restrict &();
251   };
252 
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