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