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