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 {{reinterpret_cast from 'const int structure::*' to 'void (structure::*)()' is not allowed}}
100   (void)reinterpret_cast<int structure::*>(psf); // expected-error {{reinterpret_cast from 'void (structure::*)()' 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 {{reinterpret_cast from 'int' to 'void (structure::*)()' 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);
205   (void)*reinterpret_cast<void*>(&b);
206   (void)*reinterpret_cast<void*>(&l);
207   (void)*reinterpret_cast<void*>(&d);
208   (void)*reinterpret_cast<void*>(&f);
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