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