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