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 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 
     78 C::operator const char*() const { return 0; }
     79 
     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 
     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 
    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 
    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 
    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 {{must use a typedef to declare a conversion to 'bool (&)()'}}
    176 
    177     // FIXME: This diagnostic is misleading (the correct spelling
    178     // would be 'operator int*'), but it's a corner case of a
    179     // rarely-used syntax extension.
    180     *operator int();  // expected-error {{must use a typedef to declare a conversion to 'int *'}}
    181   };
    182 }
    183 
    184 namespace smart_ptr {
    185   class Y {
    186     class YRef { };
    187 
    188     Y(Y&);
    189 
    190   public:
    191     Y();
    192     Y(YRef);
    193 
    194     operator YRef(); // expected-note{{candidate function}}
    195   };
    196 
    197   struct X { // expected-note{{candidate constructor (the implicit copy constructor) not}}
    198     explicit X(Y);
    199   };
    200 
    201   Y make_Y();
    202 
    203   X f() {
    204     X x = make_Y(); // expected-error{{no viable conversion from 'smart_ptr::Y' to 'smart_ptr::X'}}
    205     X x2(make_Y());
    206     return X(Y());
    207   }
    208 }
    209 
    210 struct Any {
    211   Any(...);
    212 };
    213 
    214 struct Other {
    215   Other(const Other &);
    216   Other();
    217 };
    218 
    219 void test_any() {
    220   Any any = Other(); // expected-error{{cannot pass object of non-POD type 'Other' through variadic constructor; call will abort at runtime}}
    221 }
    222 
    223 namespace PR7055 {
    224   // Make sure that we don't allow too many conversions in an
    225   // auto_ptr-like template. In particular, we can't create multiple
    226   // temporary objects when binding to a reference.
    227   struct auto_ptr {
    228     struct auto_ptr_ref { };
    229 
    230     auto_ptr(auto_ptr&);
    231     auto_ptr(auto_ptr_ref);
    232     explicit auto_ptr(int *);
    233 
    234     operator auto_ptr_ref();
    235   };
    236 
    237   struct X {
    238     X(auto_ptr);
    239   };
    240 
    241   X f() {
    242     X x(auto_ptr(new int));
    243     return X(auto_ptr(new int));
    244   }
    245 
    246   auto_ptr foo();
    247 
    248   X e(foo());
    249 
    250   struct Y {
    251     Y(X);
    252   };
    253 
    254   Y f2(foo());
    255 }
    256 
    257 namespace PR7934 {
    258   typedef unsigned char uint8;
    259 
    260   struct MutablePtr {
    261     MutablePtr() : ptr(0) {}
    262     void *ptr;
    263 
    264     operator void*() { return ptr; }
    265 
    266   private:
    267     operator uint8*() { return reinterpret_cast<uint8*>(ptr); }
    268     operator const char*() const { return reinterpret_cast<const char*>(ptr); }
    269   };
    270 
    271   void fake_memcpy(const void *);
    272 
    273   void use() {
    274     MutablePtr ptr;
    275     fake_memcpy(ptr);
    276   }
    277 }
    278 
    279 namespace rdar8018274 {
    280   struct X { };
    281   struct Y {
    282     operator const struct X *() const;
    283   };
    284 
    285   struct Z : Y {
    286     operator struct X * ();
    287   };
    288 
    289   void test() {
    290     Z x;
    291     (void) (x != __null);
    292   }
    293 
    294 
    295   struct Base {
    296     operator int();
    297   };
    298 
    299   struct Derived1 : Base { };
    300 
    301   struct Derived2 : Base { };
    302 
    303   struct SuperDerived : Derived1, Derived2 {
    304     using Derived1::operator int;
    305   };
    306 
    307   struct UeberDerived : SuperDerived {
    308     operator long();
    309   };
    310 
    311   void test2(UeberDerived ud) {
    312     int i = ud; // expected-error{{ambiguous conversion from derived class 'rdar8018274::SuperDerived' to base class 'rdar8018274::Base'}}
    313   }
    314 
    315   struct Base2 {
    316     operator int();
    317   };
    318 
    319   struct Base3 {
    320     operator int();
    321   };
    322 
    323   struct Derived23 : Base2, Base3 {
    324     using Base2::operator int;
    325   };
    326 
    327   struct ExtraDerived23 : Derived23 { };
    328 
    329   void test3(ExtraDerived23 ed) {
    330     int i = ed;
    331   }
    332 }
    333 
    334 namespace PR8065 {
    335   template <typename T> struct Iterator;
    336   template <typename T> struct Container;
    337 
    338   template<>
    339   struct Iterator<int> {
    340     typedef Container<int> container_type;
    341   };
    342 
    343   template <typename T>
    344   struct Container {
    345     typedef typename Iterator<T>::container_type X;
    346     operator X(void) { return X(); }
    347   };
    348 
    349   Container<int> test;
    350 }
    351 
    352 namespace PR8034 {
    353   struct C {
    354     operator int();
    355 
    356   private:
    357     template <typename T> operator T();
    358   };
    359   int x = C().operator int();
    360 }
    361 
    362 namespace PR9336 {
    363   template<class T>
    364   struct generic_list
    365   {
    366     template<class Container>
    367     operator Container()
    368     {
    369       Container ar;
    370       T* i;
    371       ar[0]=*i;
    372       return ar;
    373     }
    374   };
    375 
    376   template<class T>
    377   struct array
    378   {
    379     T& operator[](int);
    380     const T& operator[](int)const;
    381   };
    382 
    383   generic_list<generic_list<int> > l;
    384   array<array<int> > a = l;
    385 }
    386 
    387 namespace PR8800 {
    388   struct A;
    389   struct C {
    390     operator A&();
    391   };
    392   void f() {
    393     C c;
    394     A& a1(c);
    395     A& a2 = c;
    396     A& a3 = static_cast<A&>(c);
    397     A& a4 = (A&)c;
    398   }
    399 }
    400 
    401 namespace PR12712 {
    402   struct A {};
    403   struct B {
    404     operator A();
    405     operator A() const;
    406   };
    407   struct C : B {};
    408 
    409   A f(const C c) { return c; }
    410 }
    411 
    412 namespace PR18234 {
    413   struct A {
    414     operator enum E { e } (); // expected-error {{'PR18234::A::E' cannot be defined in a type specifier}}
    415     operator struct S { int n; } (); // expected-error {{'PR18234::A::S' cannot be defined in a type specifier}}
    416   } a;
    417   A::S s = a;
    418   A::E e = a; // expected-note {{here}}
    419   bool k1 = e == A::e; // expected-error {{no member named 'e'}}
    420   bool k2 = e.n == 0;
    421 }
    422