Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 class X {
      3 public:
      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 
     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 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 
     38 typedef int INT;
     39 typedef INT* INT_PTR;
     40 
     41 class 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 
     50 class A { };
     51 
     52 class B : public A {
     53 public:
     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.
     60 struct Flip;
     61 struct Flop {
     62   Flop();
     63   Flop(const Flip&); // expected-note{{candidate constructor}}
     64 };
     65 struct Flip {
     66   operator Flop() const; // expected-note{{candidate function}}
     67 };
     68 Flop 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
     71 struct C {
     72   operator const char *() const;
     73 };
     74 
     75 C::operator const char*() const { return 0; }
     76 
     77 void f(const C& c) {
     78   const char* v = c;
     79 }
     80 
     81 // Test. Conversion in base class is visible in derived class.
     82 class XB {
     83 public:
     84   operator int(); // expected-note {{candidate function}}
     85 };
     86 
     87 class Yb : public XB {
     88 public:
     89   operator char(); // expected-note {{candidate function}}
     90 };
     91 
     92 void 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.
     99 class AutoPtrRef { };
    100 
    101 class AutoPtr {
    102   AutoPtr(AutoPtr &); // expected-note{{declared private here}}
    103 
    104 public:
    105   AutoPtr();
    106   AutoPtr(AutoPtrRef);
    107 
    108   operator AutoPtrRef();
    109 };
    110 
    111 AutoPtr make_auto_ptr();
    112 
    113 AutoPtr 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 
    123 struct A1 {
    124   A1(const char *);
    125   ~A1();
    126 
    127 private:
    128   A1(const A1&); // expected-note 2 {{declared private here}}
    129 };
    130 
    131 A1 f() {
    132   // FIXME: redundant diagnostics!
    133   return "Hello"; // expected-error {{calling a private constructor}} expected-warning {{an accessible copy constructor}}
    134 }
    135 
    136 namespace 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 
    170 namespace 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 
    181 namespace 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 
    207 struct Any {
    208   Any(...);
    209 };
    210 
    211 struct Other {
    212   Other(const Other &);
    213   Other();
    214 };
    215 
    216 void 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 
    220 namespace 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 
    254 namespace 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 
    276 namespace 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 
    331 namespace 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 
    349 namespace 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 
    359 namespace 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 
    384 namespace 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 
    398 namespace 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