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.
self_conversion()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.
integral_conversion()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 
pointer_conversion()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 
constness()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 
fnptrs()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 
refs()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 
memptrs()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 // <rdar://problem/8018292>
const_arrays()130 void const_arrays() {
131   typedef char STRING[10];
132   const STRING *s;
133   const char *c;
134 
135   (void)reinterpret_cast<char *>(s); // expected-error {{reinterpret_cast from 'const STRING *' (aka 'const char (*)[10]') to 'char *' casts away qualifiers}}
136   (void)reinterpret_cast<const STRING *>(c);
137 }
138 
139 namespace PR9564 {
140   struct a { int a : 10; }; a x;
141   int *y = &reinterpret_cast<int&>(x.a); // expected-error {{reinterpret_cast from bit-field lvalue to reference type 'int &'}}
142 
143   __attribute((ext_vector_type(4))) typedef float v4;
w(v4 & a)144   float& w(v4 &a) { return reinterpret_cast<float&>(a[1]); } // expected-error {{not allowed}}
145 }
146 
dereference_reinterpret_cast()147 void dereference_reinterpret_cast() {
148   struct A {};
149   typedef A A2;
150   class B {};
151   typedef B B2;
152   A a;
153   B b;
154   A2 a2;
155   B2 b2;
156   long l;
157   double d;
158   float f;
159   char c;
160   unsigned char uc;
161   void* v_ptr;
162   (void)reinterpret_cast<double&>(l);  // expected-warning {{reinterpret_cast from 'long' to 'double &' has undefined behavior}}
163   (void)*reinterpret_cast<double*>(&l);  // expected-warning {{dereference of type 'double *' that was reinterpret_cast from type 'long *' has undefined behavior}}
164   (void)reinterpret_cast<double&>(f);  // expected-warning {{reinterpret_cast from 'float' to 'double &' has undefined behavior}}
165   (void)*reinterpret_cast<double*>(&f);  // expected-warning {{dereference of type 'double *' that was reinterpret_cast from type 'float *' has undefined behavior}}
166   (void)reinterpret_cast<float&>(l);  // expected-warning {{reinterpret_cast from 'long' to 'float &' has undefined behavior}}
167   (void)*reinterpret_cast<float*>(&l);  // expected-warning {{dereference of type 'float *' that was reinterpret_cast from type 'long *' has undefined behavior}}
168   (void)reinterpret_cast<float&>(d);  // expected-warning {{reinterpret_cast from 'double' to 'float &' has undefined behavior}}
169   (void)*reinterpret_cast<float*>(&d);  // expected-warning {{dereference of type 'float *' that was reinterpret_cast from type 'double *' has undefined behavior}}
170 
171   // TODO: add warning for tag types
172   (void)reinterpret_cast<A&>(b);
173   (void)*reinterpret_cast<A*>(&b);
174   (void)reinterpret_cast<B&>(a);
175   (void)*reinterpret_cast<B*>(&a);
176   (void)reinterpret_cast<A2&>(b2);
177   (void)*reinterpret_cast<A2*>(&b2);
178   (void)reinterpret_cast<B2&>(a2);
179   (void)*reinterpret_cast<B2*>(&a2);
180 
181   // Casting to itself is allowed
182   (void)reinterpret_cast<A&>(a);
183   (void)*reinterpret_cast<A*>(&a);
184   (void)reinterpret_cast<B&>(b);
185   (void)*reinterpret_cast<B*>(&b);
186   (void)reinterpret_cast<long&>(l);
187   (void)*reinterpret_cast<long*>(&l);
188   (void)reinterpret_cast<double&>(d);
189   (void)*reinterpret_cast<double*>(&d);
190   (void)reinterpret_cast<char&>(c);
191   (void)*reinterpret_cast<char*>(&c);
192 
193   // Casting to and from chars are allowable
194   (void)reinterpret_cast<A&>(c);
195   (void)*reinterpret_cast<A*>(&c);
196   (void)reinterpret_cast<B&>(c);
197   (void)*reinterpret_cast<B*>(&c);
198   (void)reinterpret_cast<long&>(c);
199   (void)*reinterpret_cast<long*>(&c);
200   (void)reinterpret_cast<double&>(c);
201   (void)*reinterpret_cast<double*>(&c);
202   (void)reinterpret_cast<char&>(l);
203   (void)*reinterpret_cast<char*>(&l);
204   (void)reinterpret_cast<char&>(d);
205   (void)*reinterpret_cast<char*>(&d);
206   (void)reinterpret_cast<char&>(f);
207   (void)*reinterpret_cast<char*>(&f);
208 
209   // Casting from void pointer.
210   (void)*reinterpret_cast<A*>(v_ptr);
211   (void)*reinterpret_cast<B*>(v_ptr);
212   (void)*reinterpret_cast<long*>(v_ptr);
213   (void)*reinterpret_cast<double*>(v_ptr);
214   (void)*reinterpret_cast<float*>(v_ptr);
215 
216   // Casting to void pointer
217   (void)*reinterpret_cast<void*>(&a); // expected-warning {{ISO C++ does not allow}}
218   (void)*reinterpret_cast<void*>(&b); // expected-warning {{ISO C++ does not allow}}
219   (void)*reinterpret_cast<void*>(&l); // expected-warning {{ISO C++ does not allow}}
220   (void)*reinterpret_cast<void*>(&d); // expected-warning {{ISO C++ does not allow}}
221   (void)*reinterpret_cast<void*>(&f); // expected-warning {{ISO C++ does not allow}}
222 }
223 
reinterpret_cast_whitelist()224 void reinterpret_cast_whitelist () {
225   // the dynamic type of the object
226   int a;
227   float b;
228   (void)reinterpret_cast<int&>(a);
229   (void)*reinterpret_cast<int*>(&a);
230   (void)reinterpret_cast<float&>(b);
231   (void)*reinterpret_cast<float*>(&b);
232 
233   // a cv-qualified version of the dynamic object
234   (void)reinterpret_cast<const int&>(a);
235   (void)*reinterpret_cast<const int*>(&a);
236   (void)reinterpret_cast<volatile int&>(a);
237   (void)*reinterpret_cast<volatile int*>(&a);
238   (void)reinterpret_cast<const volatile int&>(a);
239   (void)*reinterpret_cast<const volatile int*>(&a);
240   (void)reinterpret_cast<const float&>(b);
241   (void)*reinterpret_cast<const float*>(&b);
242   (void)reinterpret_cast<volatile float&>(b);
243   (void)*reinterpret_cast<volatile float*>(&b);
244   (void)reinterpret_cast<const volatile float&>(b);
245   (void)*reinterpret_cast<const volatile float*>(&b);
246 
247   // a type that is the signed or unsigned type corresponding to the dynamic
248   // type of the object
249   signed d;
250   unsigned e;
251   (void)reinterpret_cast<signed&>(d);
252   (void)*reinterpret_cast<signed*>(&d);
253   (void)reinterpret_cast<signed&>(e);
254   (void)*reinterpret_cast<signed*>(&e);
255   (void)reinterpret_cast<unsigned&>(d);
256   (void)*reinterpret_cast<unsigned*>(&d);
257   (void)reinterpret_cast<unsigned&>(e);
258   (void)*reinterpret_cast<unsigned*>(&e);
259 
260   // a type that is the signed or unsigned type corresponding a cv-qualified
261   // version of the dynamic type the object
262   (void)reinterpret_cast<const signed&>(d);
263   (void)*reinterpret_cast<const signed*>(&d);
264   (void)reinterpret_cast<const signed&>(e);
265   (void)*reinterpret_cast<const signed*>(&e);
266   (void)reinterpret_cast<const unsigned&>(d);
267   (void)*reinterpret_cast<const unsigned*>(&d);
268   (void)reinterpret_cast<const unsigned&>(e);
269   (void)*reinterpret_cast<const unsigned*>(&e);
270   (void)reinterpret_cast<volatile signed&>(d);
271   (void)*reinterpret_cast<volatile signed*>(&d);
272   (void)reinterpret_cast<volatile signed&>(e);
273   (void)*reinterpret_cast<volatile signed*>(&e);
274   (void)reinterpret_cast<volatile unsigned&>(d);
275   (void)*reinterpret_cast<volatile unsigned*>(&d);
276   (void)reinterpret_cast<volatile unsigned&>(e);
277   (void)*reinterpret_cast<volatile unsigned*>(&e);
278   (void)reinterpret_cast<const volatile signed&>(d);
279   (void)*reinterpret_cast<const volatile signed*>(&d);
280   (void)reinterpret_cast<const volatile signed&>(e);
281   (void)*reinterpret_cast<const volatile signed*>(&e);
282   (void)reinterpret_cast<const volatile unsigned&>(d);
283   (void)*reinterpret_cast<const volatile unsigned*>(&d);
284   (void)reinterpret_cast<const volatile unsigned&>(e);
285   (void)*reinterpret_cast<const volatile unsigned*>(&e);
286 
287   // an aggregate or union type that includes one of the aforementioned types
288   // among its members (including, recursively, a member of a subaggregate or
289   // contained union)
290   // TODO: checking is not implemented for tag types
291 
292   // a type that is a (possible cv-qualified) base class type of the dynamic
293   // type of the object
294   // TODO: checking is not implemented for tag types
295 
296   // a char or unsigned char type
297   (void)reinterpret_cast<char&>(a);
298   (void)*reinterpret_cast<char*>(&a);
299   (void)reinterpret_cast<unsigned char&>(a);
300   (void)*reinterpret_cast<unsigned char*>(&a);
301   (void)reinterpret_cast<char&>(b);
302   (void)*reinterpret_cast<char*>(&b);
303   (void)reinterpret_cast<unsigned char&>(b);
304   (void)*reinterpret_cast<unsigned char*>(&b);
305 }
306