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