1 // RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -Wbind-to-temporary-copy -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 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
operator const char*() const78 C::operator const char*() const { return 0; }
79
f(const C & c)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
f(Yb & a)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
test_auto_ptr(bool Cond)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
f()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
f()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
f()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
test_any()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
f()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 {
MutablePtrPR7934::MutablePtr259 MutablePtr() : ptr(0) {}
260 void *ptr;
261
operator void*PR7934::MutablePtr262 operator void*() { return ptr; }
263
264 private:
operator uint8*PR7934::MutablePtr265 operator uint8*() { return reinterpret_cast<uint8*>(ptr); }
operator const char*PR7934::MutablePtr266 operator const char*() const { return reinterpret_cast<const char*>(ptr); }
267 };
268
269 void fake_memcpy(const void *);
270
use()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
test()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
test2(UeberDerived ud)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
test3(ExtraDerived23 ed)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;
operator XPR8065::Container344 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>
operator ContainerPR9336::generic_list365 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 };
f()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
f(const C c)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