]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/SemaCXX/conversion-function.cpp
Vendor import of clang release_34 branch r197841 (effectively, 3.4 RC3):
[FreeBSD/FreeBSD.git] / test / SemaCXX / conversion-function.cpp
1 // RUN: %clang_cc1 -fsyntax-only -verify %s 
2 class X { 
3 public:
4   operator bool();
5   operator int() const;
6
7   bool f() {
8     return operator bool();
9   }
10
11   float g() {
12     return operator float(); // expected-error{{use of undeclared 'operator float'}}
13   }
14
15   static operator short(); // expected-error{{conversion function must be a non-static member function}}
16 };
17
18 operator int(); // expected-error{{conversion function must be a non-static member function}}
19
20 operator int; // expected-error{{'operator int' cannot be the name of a variable or data member}}
21
22 typedef int func_type(int);
23 typedef int array_type[10];
24
25 class Y {
26 public:
27   void operator bool(int, ...) const; // expected-error{{conversion function cannot have a return type}} \
28   // expected-error{{conversion function cannot have any parameters}}
29   
30   operator float(...) const;  // expected-error{{conversion function cannot be variadic}}
31   
32   
33   operator func_type(); // expected-error{{conversion function cannot convert to a function type}}
34   operator array_type(); // expected-error{{conversion function cannot convert to an array type}}
35 };
36
37
38 typedef int INT;
39 typedef INT* INT_PTR;
40
41 class Z { 
42   operator int(); // expected-note {{previous declaration is here}}
43   operator int**(); // expected-note {{previous declaration is here}}
44   
45   operator INT();  // expected-error{{conversion function cannot be redeclared}}
46   operator INT_PTR*(); // expected-error{{conversion function cannot be redeclared}}
47 };
48
49
50 class A { };
51
52 class B : public A {
53 public:
54   operator A&() const; // expected-warning{{conversion function converting 'B' to its base class 'A' will never be used}}
55   operator const void() const; // expected-warning{{conversion function converting 'B' to 'const void' will never be used}}
56   operator const B(); // expected-warning{{conversion function converting 'B' to itself will never be used}}
57 };
58
59 // This used to crash Clang.
60 struct Flip;
61 struct Flop {
62   Flop();
63   Flop(const Flip&); // expected-note{{candidate constructor}}
64 };
65 struct Flip {
66   operator Flop() const; // expected-note{{candidate function}}
67 };
68 Flop flop = Flip(); // expected-error {{conversion from 'Flip' to 'Flop' is ambiguous}}
69
70 // This tests that we don't add the second conversion declaration to the list of user conversions
71 struct C {
72   operator const char *() const;
73 };
74
75 C::operator const char*() const { return 0; }
76
77 void f(const C& c) {
78   const char* v = c;
79 }
80
81 // Test. Conversion in base class is visible in derived class.
82 class XB { 
83 public:
84   operator int(); // expected-note {{candidate function}}
85 };
86
87 class Yb : public XB { 
88 public:
89   operator char(); // expected-note {{candidate function}}
90 };
91
92 void f(Yb& a) {
93   if (a) { } // expected-error {{conversion from 'Yb' to 'bool' is ambiguous}}
94   int i = a; // OK. calls XB::operator int();
95   char ch = a;  // OK. calls Yb::operator char();
96 }
97
98 // Test conversion + copy construction.
99 class AutoPtrRef { };
100
101 class AutoPtr {
102   AutoPtr(AutoPtr &); // expected-note{{declared private here}}
103   
104 public:
105   AutoPtr();
106   AutoPtr(AutoPtrRef);
107   
108   operator AutoPtrRef();
109 };
110
111 AutoPtr make_auto_ptr();
112
113 AutoPtr test_auto_ptr(bool Cond) {
114   AutoPtr p1( make_auto_ptr() );
115   
116   AutoPtr p;
117   if (Cond)
118     return p; // expected-error{{calling a private constructor}}
119   
120   return AutoPtr();
121 }
122
123 struct A1 {
124   A1(const char *);
125   ~A1();
126
127 private:
128   A1(const A1&); // expected-note 2 {{declared private here}}
129 };
130
131 A1 f() {
132   // FIXME: redundant diagnostics!
133   return "Hello"; // expected-error {{calling a private constructor}} expected-warning {{an accessible copy constructor}}
134 }
135
136 namespace source_locations {
137   template<typename T>
138   struct sneaky_int {
139     typedef int type;
140   };
141
142   template<typename T, typename U>
143   struct A { };
144
145   template<typename T>
146   struct A<T, T> : A<T, int> { };
147
148   struct E {
149     template<typename T>
150     operator A<T, typename sneaky_int<T>::type>&() const; // expected-note{{candidate function}}
151   };
152
153   void f() {
154     A<float, float> &af = E(); // expected-error{{no viable conversion}}
155     A<float, int> &af2 = E();
156     const A<float, int> &caf2 = E();
157   }
158
159   // Check 
160   template<typename T>
161   struct E2 {
162     operator T
163     * // expected-error{{pointer to a reference}}
164     () const;
165   };
166
167   E2<int&> e2i; // expected-note{{in instantiation}}
168 }
169
170 namespace crazy_declarators {
171   struct A {
172     (&operator bool())(); // expected-error {{must use a typedef to declare a conversion to 'bool (&)()'}}
173
174     // FIXME: This diagnostic is misleading (the correct spelling
175     // would be 'operator int*'), but it's a corner case of a
176     // rarely-used syntax extension.
177     *operator int();  // expected-error {{must use a typedef to declare a conversion to 'int *'}}
178   };
179 }
180
181 namespace smart_ptr {
182   class Y { 
183     class YRef { };
184
185     Y(Y&);
186
187   public:
188     Y();
189     Y(YRef);
190
191     operator YRef(); // expected-note{{candidate function}}
192   };
193
194   struct X { // expected-note{{candidate constructor (the implicit copy constructor) not}}
195     explicit X(Y);
196   };
197
198   Y make_Y();
199
200   X f() {
201     X x = make_Y(); // expected-error{{no viable conversion from 'smart_ptr::Y' to 'smart_ptr::X'}}
202     X x2(make_Y());
203     return X(Y());
204   }
205 }
206
207 struct Any {
208   Any(...);
209 };
210
211 struct Other {
212   Other(const Other &); 
213   Other();
214 };
215
216 void test_any() {
217   Any any = Other(); // expected-error{{cannot pass object of non-POD type 'Other' through variadic constructor; call will abort at runtime}}
218 }
219
220 namespace PR7055 {
221   // Make sure that we don't allow too many conversions in an
222   // auto_ptr-like template. In particular, we can't create multiple
223   // temporary objects when binding to a reference.
224   struct auto_ptr {
225     struct auto_ptr_ref { };
226
227     auto_ptr(auto_ptr&);
228     auto_ptr(auto_ptr_ref);
229     explicit auto_ptr(int *);
230
231     operator auto_ptr_ref();
232   };
233
234   struct X {
235     X(auto_ptr);
236   };
237
238   X f() {
239     X x(auto_ptr(new int));
240     return X(auto_ptr(new int));
241   }
242
243   auto_ptr foo();
244
245   X e(foo());
246
247   struct Y {
248     Y(X);
249   };
250   
251   Y f2(foo());
252 }
253
254 namespace PR7934 {
255   typedef unsigned char uint8;
256
257   struct MutablePtr {
258     MutablePtr() : ptr(0) {}
259     void *ptr;
260
261     operator void*() { return ptr; }
262
263   private:
264     operator uint8*() { return reinterpret_cast<uint8*>(ptr); }
265     operator const char*() const { return reinterpret_cast<const char*>(ptr); }
266   };
267
268   void fake_memcpy(const void *);
269
270   void use() {
271     MutablePtr ptr;
272     fake_memcpy(ptr);
273   }
274 }
275
276 namespace rdar8018274 {
277   struct X { };
278   struct Y {
279     operator const struct X *() const;
280   };
281
282   struct Z : Y {
283     operator struct X * ();
284   };
285
286   void test() {
287     Z x;
288     (void) (x != __null);
289   }
290
291
292   struct Base {
293     operator int();
294   };
295
296   struct Derived1 : Base { };
297
298   struct Derived2 : Base { };
299
300   struct SuperDerived : Derived1, Derived2 { 
301     using Derived1::operator int;
302   };
303
304   struct UeberDerived : SuperDerived {
305     operator long();
306   };
307
308   void test2(UeberDerived ud) {
309     int i = ud; // expected-error{{ambiguous conversion from derived class 'rdar8018274::SuperDerived' to base class 'rdar8018274::Base'}}
310   }
311
312   struct Base2 {
313     operator int();
314   };
315
316   struct Base3 {
317     operator int();
318   };
319
320   struct Derived23 : Base2, Base3 { 
321     using Base2::operator int;
322   };
323
324   struct ExtraDerived23 : Derived23 { };
325
326   void test3(ExtraDerived23 ed) {
327     int i = ed;
328   }
329 }
330
331 namespace PR8065 {
332   template <typename T> struct Iterator;
333   template <typename T> struct Container;
334
335   template<>
336   struct Iterator<int> {
337     typedef Container<int> container_type;
338   };
339
340   template <typename T>
341   struct Container {
342     typedef typename Iterator<T>::container_type X;
343     operator X(void) { return X(); }
344   };
345
346   Container<int> test;
347 }
348
349 namespace PR8034 {
350   struct C {
351     operator int();
352
353   private:
354     template <typename T> operator T();
355   };
356   int x = C().operator int();
357 }
358
359 namespace PR9336 {
360   template<class T>
361   struct generic_list
362   {
363     template<class Container>
364     operator Container()
365     { 
366       Container ar;
367       T* i;
368       ar[0]=*i;
369       return ar;
370     }
371   };
372
373   template<class T>
374   struct array
375   {
376     T& operator[](int);
377     const T& operator[](int)const;
378   };
379
380   generic_list<generic_list<int> > l;
381   array<array<int> > a = l;
382 }
383
384 namespace PR8800 {
385   struct A;
386   struct C {
387     operator A&();
388   };
389   void f() {
390     C c;
391     A& a1(c);
392     A& a2 = c;
393     A& a3 = static_cast<A&>(c);
394     A& a4 = (A&)c;
395   }
396 }
397
398 namespace PR12712 {
399   struct A {};
400   struct B {
401     operator A();
402     operator A() const;
403   };
404   struct C : B {};
405
406   A f(const C c) { return c; }
407 }