blob: 0e7c3916171175cafa8710f9b139950a9ed1efa7 [file] [log] [blame]
Daniel Dunbar8fbe78f2009-12-15 20:14:24 +00001// RUN: %clang_cc1 -fsyntax-only -verify %s
Douglas Gregordbc5daf2008-11-07 20:08:42 +00002class X {
3public:
4 operator bool();
5 operator int() const;
Douglas Gregorae2fbad2008-11-17 20:34:05 +00006
7 bool f() {
8 return operator bool();
9 }
10
11 float g() {
John McCalld681c392009-12-16 08:11:27 +000012 return operator float(); // expected-error{{use of undeclared 'operator float'}}
Douglas Gregorae2fbad2008-11-17 20:34:05 +000013 }
Eli Friedman600bc242013-06-20 20:58:02 +000014
15 static operator short(); // expected-error{{conversion function must be a non-static member function}}
Douglas Gregordbc5daf2008-11-07 20:08:42 +000016};
17
18operator int(); // expected-error{{conversion function must be a non-static member function}}
19
Douglas Gregor92751d42008-11-17 22:58:34 +000020operator int; // expected-error{{'operator int' cannot be the name of a variable or data member}}
21
Douglas Gregordbc5daf2008-11-07 20:08:42 +000022typedef int func_type(int);
23typedef int array_type[10];
24
25class Y {
26public:
27 void operator bool(int, ...) const; // expected-error{{conversion function cannot have a return type}} \
Chris Lattnerb41df4f2009-04-25 08:35:12 +000028 // expected-error{{conversion function cannot have any parameters}}
29
30 operator float(...) const; // expected-error{{conversion function cannot be variadic}}
31
32
Douglas Gregordbc5daf2008-11-07 20:08:42 +000033 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
38typedef int INT;
39typedef INT* INT_PTR;
40
41class Z {
Chris Lattner0369c572008-11-23 23:12:31 +000042 operator int(); // expected-note {{previous declaration is here}}
43 operator int**(); // expected-note {{previous declaration is here}}
Douglas Gregordbc5daf2008-11-07 20:08:42 +000044
45 operator INT(); // expected-error{{conversion function cannot be redeclared}}
46 operator INT_PTR*(); // expected-error{{conversion function cannot be redeclared}}
47};
48
49
50class A { };
51
52class B : public A {
53public:
John McCall85f90552010-03-10 11:27:22 +000054 operator A&() const; // expected-warning{{conversion function converting 'B' to its base class 'A' will never be used}}
Chris Lattner53fa0492010-09-05 00:04:01 +000055 operator const void() const; // expected-warning{{conversion function converting 'B' to 'const void' will never be used}}
John McCall85f90552010-03-10 11:27:22 +000056 operator const B(); // expected-warning{{conversion function converting 'B' to itself will never be used}}
Douglas Gregordbc5daf2008-11-07 20:08:42 +000057};
Sebastian Redl1a99f442009-04-16 17:51:27 +000058
59// This used to crash Clang.
60struct Flip;
Douglas Gregorc779e992010-04-24 20:54:38 +000061struct Flop {
Sebastian Redl1a99f442009-04-16 17:51:27 +000062 Flop();
John McCallfd0b2f82010-01-06 09:43:14 +000063 Flop(const Flip&); // expected-note{{candidate constructor}}
Sebastian Redl1a99f442009-04-16 17:51:27 +000064};
65struct Flip {
Douglas Gregora4b592a2009-12-19 03:01:41 +000066 operator Flop() const; // expected-note{{candidate function}}
Sebastian Redl1a99f442009-04-16 17:51:27 +000067};
John McCall85f90552010-03-10 11:27:22 +000068Flop flop = Flip(); // expected-error {{conversion from 'Flip' to 'Flop' is ambiguous}}
Anders Carlsson1b12ed42009-09-13 21:33:06 +000069
70// This tests that we don't add the second conversion declaration to the list of user conversions
71struct C {
72 operator const char *() const;
73};
74
75C::operator const char*() const { return 0; }
76
77void f(const C& c) {
78 const char* v = c;
79}
Fariborz Jahanianf4061e32009-09-14 20:41:01 +000080
81// Test. Conversion in base class is visible in derived class.
82class XB {
83public:
Fariborz Jahanian19c73282009-09-15 00:10:11 +000084 operator int(); // expected-note {{candidate function}}
Fariborz Jahanianf4061e32009-09-14 20:41:01 +000085};
86
87class Yb : public XB {
88public:
Fariborz Jahanian19c73282009-09-15 00:10:11 +000089 operator char(); // expected-note {{candidate function}}
Fariborz Jahanianf4061e32009-09-14 20:41:01 +000090};
91
92void f(Yb& a) {
John McCall85f90552010-03-10 11:27:22 +000093 if (a) { } // expected-error {{conversion from 'Yb' to 'bool' is ambiguous}}
Fariborz Jahanianf4061e32009-09-14 20:41:01 +000094 int i = a; // OK. calls XB::operator int();
95 char ch = a; // OK. calls Yb::operator char();
96}
97
Douglas Gregor379d84b2009-11-13 18:44:21 +000098// Test conversion + copy construction.
99class AutoPtrRef { };
100
101class AutoPtr {
John McCall7b5f0fe2010-07-22 22:44:38 +0000102 AutoPtr(AutoPtr &); // expected-note{{declared private here}}
Douglas Gregor379d84b2009-11-13 18:44:21 +0000103
104public:
105 AutoPtr();
106 AutoPtr(AutoPtrRef);
107
108 operator AutoPtrRef();
109};
110
111AutoPtr make_auto_ptr();
112
113AutoPtr test_auto_ptr(bool Cond) {
114 AutoPtr p1( make_auto_ptr() );
115
116 AutoPtr p;
117 if (Cond)
John McCall7b5f0fe2010-07-22 22:44:38 +0000118 return p; // expected-error{{calling a private constructor}}
Douglas Gregor379d84b2009-11-13 18:44:21 +0000119
120 return AutoPtr();
121}
122
Douglas Gregore1314a62009-12-18 05:02:21 +0000123struct A1 {
124 A1(const char *);
125 ~A1();
Douglas Gregor379d84b2009-11-13 18:44:21 +0000126
Douglas Gregore1314a62009-12-18 05:02:21 +0000127private:
John McCall7b5f0fe2010-07-22 22:44:38 +0000128 A1(const A1&); // expected-note 2 {{declared private here}}
Douglas Gregore1314a62009-12-18 05:02:21 +0000129};
130
131A1 f() {
John McCall7b5f0fe2010-07-22 22:44:38 +0000132 // FIXME: redundant diagnostics!
133 return "Hello"; // expected-error {{calling a private constructor}} expected-warning {{an accessible copy constructor}}
Douglas Gregore1314a62009-12-18 05:02:21 +0000134}
Douglas Gregor5c0066f2010-04-12 23:19:01 +0000135
136namespace 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}
John McCall212fa2e2010-04-13 00:04:31 +0000169
170namespace 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}
Douglas Gregor5ab11652010-04-17 22:01:05 +0000180
181namespace 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}
Douglas Gregorc779e992010-04-24 20:54:38 +0000206
207struct Any {
208 Any(...);
209};
210
211struct Other {
212 Other(const Other &);
213 Other();
214};
215
216void 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}
Douglas Gregor836a7e82010-08-11 02:15:33 +0000219
220namespace 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}
Douglas Gregorfb640862010-08-18 21:25:30 +0000253
254namespace 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}
Douglas Gregorc9ed4682010-08-19 15:57:50 +0000275
276namespace 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 }
Douglas Gregorc0afc672010-08-19 17:02:01 +0000311
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 }
Douglas Gregorc9ed4682010-08-19 15:57:50 +0000329}
Douglas Gregor6309e3d2010-09-12 07:22:28 +0000330
331namespace 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}
Douglas Gregord5b730c92010-09-12 08:07:23 +0000348
349namespace PR8034 {
350 struct C {
351 operator int();
352
353 private:
354 template <typename T> operator T();
355 };
356 int x = C().operator int();
357}
Douglas Gregord99609a2011-03-06 09:03:20 +0000358
359namespace 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}
Richard Smith48d24642011-07-13 22:53:21 +0000383
384namespace 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}
Richard Smith99fdf8d2012-05-06 00:04:32 +0000397
398namespace 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}