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