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