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 const int ci = 0; 29 (void)reinterpret_cast<const int>(i); 30 31 structure s; 32 (void)reinterpret_cast<structure>(s); // expected-error {{reinterpret_cast from 'structure' to 'structure' is not allowed}} 33 34 float f = 0.0f; 35 (void)reinterpret_cast<float>(f); // expected-error {{reinterpret_cast from 'float' to 'float' is not allowed}} 36 } 37 38 // Test conversion between pointer and integral types, as in /3 and /4. 39 void integral_conversion() 40 { 41 void *vp = reinterpret_cast<void*>(testval); 42 intptr_t i = reinterpret_cast<intptr_t>(vp); 43 (void)reinterpret_cast<float*>(i); 44 fnptr fnp = reinterpret_cast<fnptr>(i); 45 (void)reinterpret_cast<char>(fnp); // expected-error {{cast from pointer to smaller type 'char' loses information}} 46 (void)reinterpret_cast<intptr_t>(fnp); 47 } 48 49 void pointer_conversion() 50 { 51 int *p1 = 0; 52 float *p2 = reinterpret_cast<float*>(p1); 53 structure *p3 = reinterpret_cast<structure*>(p2); 54 typedef int **ppint; 55 ppint *deep = reinterpret_cast<ppint*>(p3); 56 (void)reinterpret_cast<fnptr*>(deep); 57 } 58 59 void constness() 60 { 61 int ***const ipppc = 0; 62 // Valid: T1* -> T2 const* 63 int const *icp = reinterpret_cast<int const*>(ipppc); 64 // Invalid: T1 const* -> T2* 65 (void)reinterpret_cast<int*>(icp); // expected-error {{reinterpret_cast from 'const int *' to 'int *' casts away qualifiers}} 66 // Invalid: T1*** -> T2 const* const** 67 int const *const **icpcpp = reinterpret_cast<int const* const**>(ipppc); // expected-error {{reinterpret_cast from 'int ***' to 'const int *const **' casts away qualifiers}} 68 // Valid: T1* -> T2* 69 int *ip = reinterpret_cast<int*>(icpcpp); 70 // Valid: T* -> T const* 71 (void)reinterpret_cast<int const*>(ip); 72 // Valid: T*** -> T2 const* const* const* 73 (void)reinterpret_cast<int const* const* const*>(ipppc); 74 75 // C++ [expr.type]/8.2.2: 76 // If a pr-value initially has the type cv-T, where T is a 77 // cv-unqualified non-class, non-array type, the type of the 78 // expression is adjusted to T prior to any further analysis. 79 int i = 0; 80 // Valid: T -> T (top level const is ignored) 81 (void)reinterpret_cast<const int>(i); 82 // Valid: T* -> T* (top level const is ignored) 83 (void)reinterpret_cast<int *const>(ip); 84 } 85 86 void fnptrs() 87 { 88 typedef int (*fnptr2)(int); 89 fnptr fp = 0; 90 (void)reinterpret_cast<fnptr2>(fp); 91 void *vp = reinterpret_cast<void*>(fp); 92 (void)reinterpret_cast<fnptr>(vp); 93 } 94 95 void refs() 96 { 97 long l = 0; 98 char &c = reinterpret_cast<char&>(l); 99 // Bad: from rvalue 100 (void)reinterpret_cast<int&>(&c); // expected-error {{reinterpret_cast from rvalue to reference type 'int &'}} 101 } 102 103 void memptrs() 104 { 105 const int structure::*psi = 0; 106 (void)reinterpret_cast<const float structure::*>(psi); 107 (void)reinterpret_cast<int structure::*>(psi); // expected-error {{reinterpret_cast from 'const int structure::*' to 'int structure::*' casts away qualifiers}} 108 109 void (structure::*psf)() = 0; 110 (void)reinterpret_cast<int (structure::*)()>(psf); 111 112 (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error-re {{reinterpret_cast from 'const int structure::*' to 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' is not allowed}} 113 (void)reinterpret_cast<int structure::*>(psf); // expected-error-re {{reinterpret_cast from 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' to 'int structure::*' is not allowed}} 114 115 // Cannot cast from integers to member pointers, not even the null pointer 116 // literal. 117 (void)reinterpret_cast<void (structure::*)()>(0); // expected-error-re {{reinterpret_cast from 'int' to 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' is not allowed}} 118 (void)reinterpret_cast<int structure::*>(0); // expected-error {{reinterpret_cast from 'int' to 'int structure::*' is not allowed}} 119 } 120 121 namespace PR5545 { 122 // PR5545 123 class A; 124 class B; 125 void (A::*a)(); 126 void (B::*b)() = reinterpret_cast<void (B::*)()>(a); 127 } 128 129 void const_arrays() { 130 typedef char STRING[10]; 131 const STRING *s; 132 const char *c; 133 134 (void)reinterpret_cast<char *>(s); // expected-error {{reinterpret_cast from 'const STRING *' (aka 'const char (*)[10]') to 'char *' casts away qualifiers}} 135 (void)reinterpret_cast<const STRING *>(c); 136 } 137 138 namespace PR9564 { 139 struct a { int a : 10; }; a x; 140 int *y = &reinterpret_cast<int&>(x.a); // expected-error {{reinterpret_cast from bit-field lvalue to reference type 'int &'}} 141 142 __attribute((ext_vector_type(4))) typedef float v4; 143 float& w(v4 &a) { return reinterpret_cast<float&>(a[1]); } // expected-error {{not allowed}} 144 } 145 146 void dereference_reinterpret_cast() { 147 struct A {}; 148 typedef A A2; 149 class B {}; 150 typedef B B2; 151 A a; 152 B b; 153 A2 a2; 154 B2 b2; 155 long l; 156 double d; 157 float f; 158 char c; 159 unsigned char uc; 160 void* v_ptr; 161 (void)reinterpret_cast<double&>(l); // expected-warning {{reinterpret_cast from 'long' to 'double &' has undefined behavior}} 162 (void)*reinterpret_cast<double*>(&l); // expected-warning {{dereference of type 'double *' that was reinterpret_cast from type 'long *' has undefined behavior}} 163 (void)reinterpret_cast<double&>(f); // expected-warning {{reinterpret_cast from 'float' to 'double &' has undefined behavior}} 164 (void)*reinterpret_cast<double*>(&f); // expected-warning {{dereference of type 'double *' that was reinterpret_cast from type 'float *' has undefined behavior}} 165 (void)reinterpret_cast<float&>(l); // expected-warning {{reinterpret_cast from 'long' to 'float &' has undefined behavior}} 166 (void)*reinterpret_cast<float*>(&l); // expected-warning {{dereference of type 'float *' that was reinterpret_cast from type 'long *' has undefined behavior}} 167 (void)reinterpret_cast<float&>(d); // expected-warning {{reinterpret_cast from 'double' to 'float &' has undefined behavior}} 168 (void)*reinterpret_cast<float*>(&d); // expected-warning {{dereference of type 'float *' that was reinterpret_cast from type 'double *' has undefined behavior}} 169 170 // TODO: add warning for tag types 171 (void)reinterpret_cast<A&>(b); 172 (void)*reinterpret_cast<A*>(&b); 173 (void)reinterpret_cast<B&>(a); 174 (void)*reinterpret_cast<B*>(&a); 175 (void)reinterpret_cast<A2&>(b2); 176 (void)*reinterpret_cast<A2*>(&b2); 177 (void)reinterpret_cast<B2&>(a2); 178 (void)*reinterpret_cast<B2*>(&a2); 179 180 // Casting to itself is allowed 181 (void)reinterpret_cast<A&>(a); 182 (void)*reinterpret_cast<A*>(&a); 183 (void)reinterpret_cast<B&>(b); 184 (void)*reinterpret_cast<B*>(&b); 185 (void)reinterpret_cast<long&>(l); 186 (void)*reinterpret_cast<long*>(&l); 187 (void)reinterpret_cast<double&>(d); 188 (void)*reinterpret_cast<double*>(&d); 189 (void)reinterpret_cast<char&>(c); 190 (void)*reinterpret_cast<char*>(&c); 191 192 // Casting to and from chars are allowable 193 (void)reinterpret_cast<A&>(c); 194 (void)*reinterpret_cast<A*>(&c); 195 (void)reinterpret_cast<B&>(c); 196 (void)*reinterpret_cast<B*>(&c); 197 (void)reinterpret_cast<long&>(c); 198 (void)*reinterpret_cast<long*>(&c); 199 (void)reinterpret_cast<double&>(c); 200 (void)*reinterpret_cast<double*>(&c); 201 (void)reinterpret_cast<char&>(l); 202 (void)*reinterpret_cast<char*>(&l); 203 (void)reinterpret_cast<char&>(d); 204 (void)*reinterpret_cast<char*>(&d); 205 (void)reinterpret_cast<char&>(f); 206 (void)*reinterpret_cast<char*>(&f); 207 208 // Casting from void pointer. 209 (void)*reinterpret_cast<A*>(v_ptr); 210 (void)*reinterpret_cast<B*>(v_ptr); 211 (void)*reinterpret_cast<long*>(v_ptr); 212 (void)*reinterpret_cast<double*>(v_ptr); 213 (void)*reinterpret_cast<float*>(v_ptr); 214 215 // Casting to void pointer 216 (void)*reinterpret_cast<void*>(&a); // expected-error {{indirection not permitted on operand of type 'void *'}} 217 (void)*reinterpret_cast<void*>(&b); // expected-error {{indirection not permitted on operand of type 'void *'}} 218 (void)*reinterpret_cast<void*>(&l); // expected-error {{indirection not permitted on operand of type 'void *'}} 219 (void)*reinterpret_cast<void*>(&d); // expected-error {{indirection not permitted on operand of type 'void *'}} 220 (void)*reinterpret_cast<void*>(&f); // expected-error {{indirection not permitted on operand of type 'void *'}} 221 } 222 223 void reinterpret_cast_allowlist () { 224 // the dynamic type of the object 225 int a; 226 float b; 227 (void)reinterpret_cast<int&>(a); 228 (void)*reinterpret_cast<int*>(&a); 229 (void)reinterpret_cast<float&>(b); 230 (void)*reinterpret_cast<float*>(&b); 231 232 // a cv-qualified version of the dynamic object 233 (void)reinterpret_cast<const int&>(a); 234 (void)*reinterpret_cast<const int*>(&a); 235 (void)reinterpret_cast<volatile int&>(a); 236 (void)*reinterpret_cast<volatile int*>(&a); 237 (void)reinterpret_cast<const volatile int&>(a); 238 (void)*reinterpret_cast<const volatile int*>(&a); 239 (void)reinterpret_cast<const float&>(b); 240 (void)*reinterpret_cast<const float*>(&b); 241 (void)reinterpret_cast<volatile float&>(b); 242 (void)*reinterpret_cast<volatile float*>(&b); 243 (void)reinterpret_cast<const volatile float&>(b); 244 (void)*reinterpret_cast<const volatile float*>(&b); 245 246 // a type that is the signed or unsigned type corresponding to the dynamic 247 // type of the object 248 signed d; 249 unsigned e; 250 (void)reinterpret_cast<signed&>(d); 251 (void)*reinterpret_cast<signed*>(&d); 252 (void)reinterpret_cast<signed&>(e); 253 (void)*reinterpret_cast<signed*>(&e); 254 (void)reinterpret_cast<unsigned&>(d); 255 (void)*reinterpret_cast<unsigned*>(&d); 256 (void)reinterpret_cast<unsigned&>(e); 257 (void)*reinterpret_cast<unsigned*>(&e); 258 259 // a type that is the signed or unsigned type corresponding a cv-qualified 260 // version of the dynamic type the object 261 (void)reinterpret_cast<const signed&>(d); 262 (void)*reinterpret_cast<const signed*>(&d); 263 (void)reinterpret_cast<const signed&>(e); 264 (void)*reinterpret_cast<const signed*>(&e); 265 (void)reinterpret_cast<const unsigned&>(d); 266 (void)*reinterpret_cast<const unsigned*>(&d); 267 (void)reinterpret_cast<const unsigned&>(e); 268 (void)*reinterpret_cast<const unsigned*>(&e); 269 (void)reinterpret_cast<volatile signed&>(d); 270 (void)*reinterpret_cast<volatile signed*>(&d); 271 (void)reinterpret_cast<volatile signed&>(e); 272 (void)*reinterpret_cast<volatile signed*>(&e); 273 (void)reinterpret_cast<volatile unsigned&>(d); 274 (void)*reinterpret_cast<volatile unsigned*>(&d); 275 (void)reinterpret_cast<volatile unsigned&>(e); 276 (void)*reinterpret_cast<volatile unsigned*>(&e); 277 (void)reinterpret_cast<const volatile signed&>(d); 278 (void)*reinterpret_cast<const volatile signed*>(&d); 279 (void)reinterpret_cast<const volatile signed&>(e); 280 (void)*reinterpret_cast<const volatile signed*>(&e); 281 (void)reinterpret_cast<const volatile unsigned&>(d); 282 (void)*reinterpret_cast<const volatile unsigned*>(&d); 283 (void)reinterpret_cast<const volatile unsigned&>(e); 284 (void)*reinterpret_cast<const volatile unsigned*>(&e); 285 286 // an aggregate or union type that includes one of the aforementioned types 287 // among its members (including, recursively, a member of a subaggregate or 288 // contained union) 289 // TODO: checking is not implemented for tag types 290 291 // a type that is a (possible cv-qualified) base class type of the dynamic 292 // type of the object 293 // TODO: checking is not implemented for tag types 294 295 // a char or unsigned char type 296 (void)reinterpret_cast<char&>(a); 297 (void)*reinterpret_cast<char*>(&a); 298 (void)reinterpret_cast<unsigned char&>(a); 299 (void)*reinterpret_cast<unsigned char*>(&a); 300 (void)reinterpret_cast<char&>(b); 301 (void)*reinterpret_cast<char*>(&b); 302 (void)reinterpret_cast<unsigned char&>(b); 303 (void)*reinterpret_cast<unsigned char*>(&b); 304 } 305 306 namespace templated { 307 template <typename TARGETTYPE, typename UATYPE> 308 void cast_uninstantiated() { 309 const UATYPE* data; 310 (void)*reinterpret_cast<const TARGETTYPE*>(data); // no warning 311 } 312 313 314 template <typename TARGETTYPE, typename UATYPE> 315 void cast_instantiated_badly() { 316 const UATYPE* data; 317 (void)*reinterpret_cast<const TARGETTYPE*>(data); // expected-warning {{dereference of type 'const int *' that was reinterpret_cast from type 'const float *' has undefined behavior}} 318 } 319 320 template <typename TARGETTYPE, typename UATYPE> 321 void cast_instantiated_well() { 322 const UATYPE* data; 323 (void)*reinterpret_cast<const TARGETTYPE*>(data); // no warning 324 } 325 326 template <typename TARGETTYPE> 327 void cast_one_tmpl_arg_uninstantiated() { 328 const int* data; 329 (void)*reinterpret_cast<const TARGETTYPE*>(data); // no warning 330 } 331 332 template <typename TARGETTYPE> 333 void cast_one_tmpl_arg_instantiated_badly() { 334 const float* data; 335 (void)*reinterpret_cast<const TARGETTYPE*>(data); // expected-warning {{dereference of type 'const int *' that was reinterpret_cast from type 'const float *' has undefined behavior}} 336 } 337 338 template <typename TARGETTYPE> 339 void cast_one_tmpl_arg_instantiated_well() { 340 const float* data; 341 (void)*reinterpret_cast<const TARGETTYPE*>(data); // no warning 342 } 343 344 template <int size> 345 void cast_nontype_template_true_positive_noninstantiated() { 346 const float *data; 347 const int arr[size]; 348 (void)*reinterpret_cast<const int*>(data); // expected-warning {{dereference of type 'const int *' that was reinterpret_cast from type 'const float *' has undefined behavior}} 349 } 350 351 template <int size> 352 void cast_nontype_template_true_negative_noninstantiated() { 353 const int data[size]; 354 (void)*reinterpret_cast<const int*>(data); // no warning 355 } 356 357 void top() { 358 cast_instantiated_badly<int, float>(); 359 // expected-note@-1 {{in instantiation of function template specialization 'templated::cast_instantiated_badly<int, float>' requested here}} 360 cast_instantiated_well<int, int>(); 361 cast_one_tmpl_arg_instantiated_badly<int>(); 362 // expected-note@-1 {{in instantiation of function template specialization 'templated::cast_one_tmpl_arg_instantiated_badly<int>' requested here}} 363 cast_one_tmpl_arg_instantiated_well<float>(); 364 } 365 366 template<typename T, typename U> 367 void cast_template_dependent_type_noninstantiated(T** x) 368 { 369 (void)*reinterpret_cast<U**>(x); 370 } 371 372 template<typename T, typename U> 373 void cast_template_dependent_member_type_noninstantiated(typename T::X x) 374 { 375 (void)*reinterpret_cast<typename U::Y>(x); 376 } 377 378 } // namespace templated 379