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 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.
integral_conversion()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
pointer_conversion()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
constness()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
fnptrs()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
refs()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
memptrs()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-re {{reinterpret_cast from 'const int structure::*' to 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' is not allowed}}
100 (void)reinterpret_cast<int structure::*>(psf); // expected-error-re {{reinterpret_cast from 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' 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-re {{reinterpret_cast from 'int' to 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' 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>
const_arrays()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;
w(v4 & a)131 float& w(v4 &a) { return reinterpret_cast<float&>(a[1]); } // expected-error {{not allowed}}
132 }
133
dereference_reinterpret_cast()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); // expected-warning {{ISO C++ does not allow}}
205 (void)*reinterpret_cast<void*>(&b); // expected-warning {{ISO C++ does not allow}}
206 (void)*reinterpret_cast<void*>(&l); // expected-warning {{ISO C++ does not allow}}
207 (void)*reinterpret_cast<void*>(&d); // expected-warning {{ISO C++ does not allow}}
208 (void)*reinterpret_cast<void*>(&f); // expected-warning {{ISO C++ does not allow}}
209 }
210
reinterpret_cast_whitelist()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