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