Clang Project

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