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