Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding -Wundefined-reinterpret-cast %s
      2 
      3 #include <stdint.h>
      4 
      5 enum test { testval = 1 };
      6 struct structure { int m; };
      7 typedef void (*fnptr)();
      8 
      9 // Test the conversion to self.
     10 void self_conversion()
     11 {
     12   // T*->T* is allowed, T->T in general not.
     13   int i = 0;
     14   (void)reinterpret_cast<int>(i); // expected-error {{reinterpret_cast from 'int' to 'int' is not allowed}}
     15   structure s;
     16   (void)reinterpret_cast<structure>(s); // expected-error {{reinterpret_cast from 'structure' to 'structure' is not allowed}}
     17   int *pi = 0;
     18   (void)reinterpret_cast<int*>(pi);
     19 }
     20 
     21 // Test conversion between pointer and integral types, as in /3 and /4.
     22 void integral_conversion()
     23 {
     24   void *vp = reinterpret_cast<void*>(testval);
     25   intptr_t i = reinterpret_cast<intptr_t>(vp);
     26   (void)reinterpret_cast<float*>(i);
     27   fnptr fnp = reinterpret_cast<fnptr>(i);
     28   (void)reinterpret_cast<char>(fnp); // expected-error {{cast from pointer to smaller type 'char' loses information}}
     29   (void)reinterpret_cast<intptr_t>(fnp);
     30 }
     31 
     32 void pointer_conversion()
     33 {
     34   int *p1 = 0;
     35   float *p2 = reinterpret_cast<float*>(p1);
     36   structure *p3 = reinterpret_cast<structure*>(p2);
     37   typedef int **ppint;
     38   ppint *deep = reinterpret_cast<ppint*>(p3);
     39   (void)reinterpret_cast<fnptr*>(deep);
     40 }
     41 
     42 void constness()
     43 {
     44   int ***const ipppc = 0;
     45   // Valid: T1* -> T2 const*
     46   int const *icp = reinterpret_cast<int const*>(ipppc);
     47   // Invalid: T1 const* -> T2*
     48   (void)reinterpret_cast<int*>(icp); // expected-error {{reinterpret_cast from 'const int *' to 'int *' casts away qualifiers}}
     49   // Invalid: T1*** -> T2 const* const**
     50   int const *const **icpcpp = reinterpret_cast<int const* const**>(ipppc); // expected-error {{reinterpret_cast from 'int ***' to 'const int *const **' casts away qualifiers}}
     51   // Valid: T1* -> T2*
     52   int *ip = reinterpret_cast<int*>(icpcpp);
     53   // Valid: T* -> T const*
     54   (void)reinterpret_cast<int const*>(ip);
     55   // Valid: T*** -> T2 const* const* const*
     56   (void)reinterpret_cast<int const* const* const*>(ipppc);
     57 }
     58 
     59 void fnptrs()
     60 {
     61   typedef int (*fnptr2)(int);
     62   fnptr fp = 0;
     63   (void)reinterpret_cast<fnptr2>(fp);
     64   void *vp = reinterpret_cast<void*>(fp);
     65   (void)reinterpret_cast<fnptr>(vp);
     66 }
     67 
     68 void refs()
     69 {
     70   long l = 0;
     71   char &c = reinterpret_cast<char&>(l);
     72   // Bad: from rvalue
     73   (void)reinterpret_cast<int&>(&c); // expected-error {{reinterpret_cast from rvalue to reference type 'int &'}}
     74 }
     75 
     76 void memptrs()
     77 {
     78   const int structure::*psi = 0;
     79   (void)reinterpret_cast<const float structure::*>(psi);
     80   (void)reinterpret_cast<int structure::*>(psi); // expected-error {{reinterpret_cast from 'const int structure::*' to 'int structure::*' casts away qualifiers}}
     81 
     82   void (structure::*psf)() = 0;
     83   (void)reinterpret_cast<int (structure::*)()>(psf);
     84 
     85   (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error {{reinterpret_cast from 'const int structure::*' to 'void (structure::*)()' is not allowed}}
     86   (void)reinterpret_cast<int structure::*>(psf); // expected-error {{reinterpret_cast from 'void (structure::*)()' to 'int structure::*' is not allowed}}
     87 
     88   // Cannot cast from integers to member pointers, not even the null pointer
     89   // literal.
     90   (void)reinterpret_cast<void (structure::*)()>(0); // expected-error {{reinterpret_cast from 'int' to 'void (structure::*)()' is not allowed}}
     91   (void)reinterpret_cast<int structure::*>(0); // expected-error {{reinterpret_cast from 'int' to 'int structure::*' is not allowed}}
     92 }
     93 
     94 namespace PR5545 {
     95 // PR5545
     96 class A;
     97 class B;
     98 void (A::*a)();
     99 void (B::*b)() = reinterpret_cast<void (B::*)()>(a);
    100 }
    101 
    102 // <rdar://problem/8018292>
    103 void const_arrays() {
    104   typedef char STRING[10];
    105   const STRING *s;
    106   const char *c;
    107 
    108   (void)reinterpret_cast<char *>(s); // expected-error {{reinterpret_cast from 'const STRING *' (aka 'char const (*)[10]') to 'char *' casts away qualifiers}}
    109   (void)reinterpret_cast<const STRING *>(c);
    110 }
    111 
    112 namespace PR9564 {
    113   struct a { int a : 10; }; a x;
    114   int *y = &reinterpret_cast<int&>(x.a); // expected-error {{not allowed}}
    115 
    116   __attribute((ext_vector_type(4))) typedef float v4;
    117   float& w(v4 &a) { return reinterpret_cast<float&>(a[1]); } // expected-error {{not allowed}}
    118 }
    119 
    120 void dereference_reinterpret_cast() {
    121   struct A {};
    122   typedef A A2;
    123   class B {};
    124   typedef B B2;
    125   A a;
    126   B b;
    127   A2 a2;
    128   B2 b2;
    129   long l;
    130   double d;
    131   float f;
    132   char c;
    133   unsigned char uc;
    134   void* v_ptr;
    135   (void)reinterpret_cast<double&>(l);  // expected-warning {{reinterpret_cast from 'long' to 'double &' has undefined behavior}}
    136   (void)*reinterpret_cast<double*>(&l);  // expected-warning {{dereference of type 'double *' that was reinterpret_cast from type 'long *' has undefined behavior}}
    137   (void)reinterpret_cast<double&>(f);  // expected-warning {{reinterpret_cast from 'float' to 'double &' has undefined behavior}}
    138   (void)*reinterpret_cast<double*>(&f);  // expected-warning {{dereference of type 'double *' that was reinterpret_cast from type 'float *' has undefined behavior}}
    139   (void)reinterpret_cast<float&>(l);  // expected-warning {{reinterpret_cast from 'long' to 'float &' has undefined behavior}}
    140   (void)*reinterpret_cast<float*>(&l);  // expected-warning {{dereference of type 'float *' that was reinterpret_cast from type 'long *' has undefined behavior}}
    141   (void)reinterpret_cast<float&>(d);  // expected-warning {{reinterpret_cast from 'double' to 'float &' has undefined behavior}}
    142   (void)*reinterpret_cast<float*>(&d);  // expected-warning {{dereference of type 'float *' that was reinterpret_cast from type 'double *' has undefined behavior}}
    143 
    144   // TODO: add warning for tag types
    145   (void)reinterpret_cast<A&>(b);
    146   (void)*reinterpret_cast<A*>(&b);
    147   (void)reinterpret_cast<B&>(a);
    148   (void)*reinterpret_cast<B*>(&a);
    149   (void)reinterpret_cast<A2&>(b2);
    150   (void)*reinterpret_cast<A2*>(&b2);
    151   (void)reinterpret_cast<B2&>(a2);
    152   (void)*reinterpret_cast<B2*>(&a2);
    153 
    154   // Casting to itself is allowed
    155   (void)reinterpret_cast<A&>(a);
    156   (void)*reinterpret_cast<A*>(&a);
    157   (void)reinterpret_cast<B&>(b);
    158   (void)*reinterpret_cast<B*>(&b);
    159   (void)reinterpret_cast<long&>(l);
    160   (void)*reinterpret_cast<long*>(&l);
    161   (void)reinterpret_cast<double&>(d);
    162   (void)*reinterpret_cast<double*>(&d);
    163   (void)reinterpret_cast<char&>(c);
    164   (void)*reinterpret_cast<char*>(&c);
    165 
    166   // Casting to and from chars are allowable
    167   (void)reinterpret_cast<A&>(c);
    168   (void)*reinterpret_cast<A*>(&c);
    169   (void)reinterpret_cast<B&>(c);
    170   (void)*reinterpret_cast<B*>(&c);
    171   (void)reinterpret_cast<long&>(c);
    172   (void)*reinterpret_cast<long*>(&c);
    173   (void)reinterpret_cast<double&>(c);
    174   (void)*reinterpret_cast<double*>(&c);
    175   (void)reinterpret_cast<char&>(l);
    176   (void)*reinterpret_cast<char*>(&l);
    177   (void)reinterpret_cast<char&>(d);
    178   (void)*reinterpret_cast<char*>(&d);
    179   (void)reinterpret_cast<char&>(f);
    180   (void)*reinterpret_cast<char*>(&f);
    181 
    182   // Casting from void pointer.
    183   (void)*reinterpret_cast<A*>(v_ptr);
    184   (void)*reinterpret_cast<B*>(v_ptr);
    185   (void)*reinterpret_cast<long*>(v_ptr);
    186   (void)*reinterpret_cast<double*>(v_ptr);
    187   (void)*reinterpret_cast<float*>(v_ptr);
    188 
    189   // Casting to void pointer
    190   (void)*reinterpret_cast<void*>(&a);
    191   (void)*reinterpret_cast<void*>(&b);
    192   (void)*reinterpret_cast<void*>(&l);
    193   (void)*reinterpret_cast<void*>(&d);
    194   (void)*reinterpret_cast<void*>(&f);
    195 }
    196 
    197 void reinterpret_cast_whitelist () {
    198   // the dynamic type of the object
    199   int a;
    200   float b;
    201   (void)reinterpret_cast<int&>(a);
    202   (void)*reinterpret_cast<int*>(&a);
    203   (void)reinterpret_cast<float&>(b);
    204   (void)*reinterpret_cast<float*>(&b);
    205 
    206   // a cv-qualified version of the dynamic object
    207   (void)reinterpret_cast<const int&>(a);
    208   (void)*reinterpret_cast<const int*>(&a);
    209   (void)reinterpret_cast<volatile int&>(a);
    210   (void)*reinterpret_cast<volatile int*>(&a);
    211   (void)reinterpret_cast<const volatile int&>(a);
    212   (void)*reinterpret_cast<const volatile int*>(&a);
    213   (void)reinterpret_cast<const float&>(b);
    214   (void)*reinterpret_cast<const float*>(&b);
    215   (void)reinterpret_cast<volatile float&>(b);
    216   (void)*reinterpret_cast<volatile float*>(&b);
    217   (void)reinterpret_cast<const volatile float&>(b);
    218   (void)*reinterpret_cast<const volatile float*>(&b);
    219 
    220   // a type that is the signed or unsigned type corresponding to the dynamic
    221   // type of the object
    222   signed d;
    223   unsigned e;
    224   (void)reinterpret_cast<signed&>(d);
    225   (void)*reinterpret_cast<signed*>(&d);
    226   (void)reinterpret_cast<signed&>(e);
    227   (void)*reinterpret_cast<signed*>(&e);
    228   (void)reinterpret_cast<unsigned&>(d);
    229   (void)*reinterpret_cast<unsigned*>(&d);
    230   (void)reinterpret_cast<unsigned&>(e);
    231   (void)*reinterpret_cast<unsigned*>(&e);
    232 
    233   // a type that is the signed or unsigned type corresponding a cv-qualified
    234   // version of the dynamic type the object
    235   (void)reinterpret_cast<const signed&>(d);
    236   (void)*reinterpret_cast<const signed*>(&d);
    237   (void)reinterpret_cast<const signed&>(e);
    238   (void)*reinterpret_cast<const signed*>(&e);
    239   (void)reinterpret_cast<const unsigned&>(d);
    240   (void)*reinterpret_cast<const unsigned*>(&d);
    241   (void)reinterpret_cast<const unsigned&>(e);
    242   (void)*reinterpret_cast<const unsigned*>(&e);
    243   (void)reinterpret_cast<volatile signed&>(d);
    244   (void)*reinterpret_cast<volatile signed*>(&d);
    245   (void)reinterpret_cast<volatile signed&>(e);
    246   (void)*reinterpret_cast<volatile signed*>(&e);
    247   (void)reinterpret_cast<volatile unsigned&>(d);
    248   (void)*reinterpret_cast<volatile unsigned*>(&d);
    249   (void)reinterpret_cast<volatile unsigned&>(e);
    250   (void)*reinterpret_cast<volatile unsigned*>(&e);
    251   (void)reinterpret_cast<const volatile signed&>(d);
    252   (void)*reinterpret_cast<const volatile signed*>(&d);
    253   (void)reinterpret_cast<const volatile signed&>(e);
    254   (void)*reinterpret_cast<const volatile signed*>(&e);
    255   (void)reinterpret_cast<const volatile unsigned&>(d);
    256   (void)*reinterpret_cast<const volatile unsigned*>(&d);
    257   (void)reinterpret_cast<const volatile unsigned&>(e);
    258   (void)*reinterpret_cast<const volatile unsigned*>(&e);
    259 
    260   // an aggregate or union type that includes one of the aforementioned types
    261   // among its members (including, recursively, a member of a subaggregate or
    262   // contained union)
    263   // TODO: checking is not implemented for tag types
    264 
    265   // a type that is a (possible cv-qualified) base class type of the dynamic
    266   // type of the object
    267   // TODO: checking is not implemented for tag types
    268 
    269   // a char or unsigned char type
    270   (void)reinterpret_cast<char&>(a);
    271   (void)*reinterpret_cast<char*>(&a);
    272   (void)reinterpret_cast<unsigned char&>(a);
    273   (void)*reinterpret_cast<unsigned char*>(&a);
    274   (void)reinterpret_cast<char&>(b);
    275   (void)*reinterpret_cast<char*>(&b);
    276   (void)reinterpret_cast<unsigned char&>(b);
    277   (void)*reinterpret_cast<unsigned char*>(&b);
    278 }
    279