1 // RUN: %clang_cc1 -fsyntax-only -Wbind-to-temporary-copy -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 {{use a typedef to declare a conversion to 'bool (&)()'}}
176     *operator int();  // expected-error {{put the complete type after 'operator'}}
177     // No suggestion of using a typedef here; that's not possible.
178     template<typename T> (&operator T())(); // expected-error-re {{cannot specify any part of a return type in the declaration of a conversion function{{$}}}}
179   };
180 }
181 
182 namespace smart_ptr {
183   class Y {
184     class YRef { };
185 
186     Y(Y&);
187 
188   public:
189     Y();
190     Y(YRef);
191 
192     operator YRef(); // expected-note{{candidate function}}
193   };
194 
195   struct X { // expected-note{{candidate constructor (the implicit copy constructor) not}}
196     explicit X(Y);
197   };
198 
199   Y make_Y();
200 
201   X f() {
202     X x = make_Y(); // expected-error{{no viable conversion from 'smart_ptr::Y' to 'smart_ptr::X'}}
203     X x2(make_Y());
204     return X(Y());
205   }
206 }
207 
208 struct Any {
209   Any(...);
210 };
211 
212 struct Other {
213   Other(const Other &);
214   Other();
215 };
216 
217 void test_any() {
218   Any any = Other(); // expected-error{{cannot pass object of non-POD type 'Other' through variadic constructor; call will abort at runtime}}
219 }
220 
221 namespace PR7055 {
222   // Make sure that we don't allow too many conversions in an
223   // auto_ptr-like template. In particular, we can't create multiple
224   // temporary objects when binding to a reference.
225   struct auto_ptr {
226     struct auto_ptr_ref { };
227 
228     auto_ptr(auto_ptr&);
229     auto_ptr(auto_ptr_ref);
230     explicit auto_ptr(int *);
231 
232     operator auto_ptr_ref();
233   };
234 
235   struct X {
236     X(auto_ptr);
237   };
238 
239   X f() {
240     X x(auto_ptr(new int));
241     return X(auto_ptr(new int));
242   }
243 
244   auto_ptr foo();
245 
246   X e(foo());
247 
248   struct Y {
249     Y(X);
250   };
251 
252   Y f2(foo());
253 }
254 
255 namespace PR7934 {
256   typedef unsigned char uint8;
257 
258   struct MutablePtr {
259     MutablePtr() : ptr(0) {}
260     void *ptr;
261 
262     operator void*() { return ptr; }
263 
264   private:
265     operator uint8*() { return reinterpret_cast<uint8*>(ptr); }
266     operator const char*() const { return reinterpret_cast<const char*>(ptr); }
267   };
268 
269   void fake_memcpy(const void *);
270 
271   void use() {
272     MutablePtr ptr;
273     fake_memcpy(ptr);
274   }
275 }
276 
277 namespace rdar8018274 {
278   struct X { };
279   struct Y {
280     operator const struct X *() const;
281   };
282 
283   struct Z : Y {
284     operator struct X * ();
285   };
286 
287   void test() {
288     Z x;
289     (void) (x != __null);
290   }
291 
292 
293   struct Base {
294     operator int();
295   };
296 
297   struct Derived1 : Base { };
298 
299   struct Derived2 : Base { };
300 
301   struct SuperDerived : Derived1, Derived2 {
302     using Derived1::operator int;
303   };
304 
305   struct UeberDerived : SuperDerived {
306     operator long();
307   };
308 
309   void test2(UeberDerived ud) {
310     int i = ud; // expected-error{{ambiguous conversion from derived class 'rdar8018274::SuperDerived' to base class 'rdar8018274::Base'}}
311   }
312 
313   struct Base2 {
314     operator int();
315   };
316 
317   struct Base3 {
318     operator int();
319   };
320 
321   struct Derived23 : Base2, Base3 {
322     using Base2::operator int;
323   };
324 
325   struct ExtraDerived23 : Derived23 { };
326 
327   void test3(ExtraDerived23 ed) {
328     int i = ed;
329   }
330 }
331 
332 namespace PR8065 {
333   template <typename T> struct Iterator;
334   template <typename T> struct Container;
335 
336   template<>
337   struct Iterator<int> {
338     typedef Container<int> container_type;
339   };
340 
341   template <typename T>
342   struct Container {
343     typedef typename Iterator<T>::container_type X;
344     operator X(void) { return X(); }
345   };
346 
347   Container<int> test;
348 }
349 
350 namespace PR8034 {
351   struct C {
352     operator int();
353 
354   private:
355     template <typename T> operator T();
356   };
357   int x = C().operator int();
358 }
359 
360 namespace PR9336 {
361   template<class T>
362   struct generic_list
363   {
364     template<class Container>
365     operator Container()
366     {
367       Container ar;
368       T* i;
369       ar[0]=*i;
370       return ar;
371     }
372   };
373 
374   template<class T>
375   struct array
376   {
377     T& operator[](int);
378     const T& operator[](int)const;
379   };
380 
381   generic_list<generic_list<int> > l;
382   array<array<int> > a = l;
383 }
384 
385 namespace PR8800 {
386   struct A;
387   struct C {
388     operator A&();
389   };
390   void f() {
391     C c;
392     A& a1(c);
393     A& a2 = c;
394     A& a3 = static_cast<A&>(c);
395     A& a4 = (A&)c;
396   }
397 }
398 
399 namespace PR12712 {
400   struct A {};
401   struct B {
402     operator A();
403     operator A() const;
404   };
405   struct C : B {};
406 
407   A f(const C c) { return c; }
408 }
409 
410 namespace PR18234 {
411   struct A {
412     operator enum E { e } (); // expected-error {{'PR18234::A::E' cannot be defined in a type specifier}}
413     operator struct S { int n; } (); // expected-error {{'PR18234::A::S' cannot be defined in a type specifier}}
414   } a;
415   A::S s = a;
416   A::E e = a; // expected-note {{here}}
417   bool k1 = e == A::e; // expected-error {{no member named 'e'}}
418   bool k2 = e.n == 0;
419 }
420