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