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