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