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