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