1 // RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding -Wundefined-reinterpret-cast -Wno-unused-volatile-lvalue %s
5 enum test
{ testval
= 1 };
6 struct structure
{ int m
; };
7 typedef void (*fnptr
)();
9 // Test the conversion to self.
10 void self_conversion()
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
16 (void)reinterpret_cast<int>(i
);
19 (void)reinterpret_cast<test
>(e
);
23 (void)reinterpret_cast<int*>(pi
);
25 const int structure::*psi
= 0;
26 (void)reinterpret_cast<const int structure::*>(psi
);
29 (void)reinterpret_cast<const int>(i
);
32 (void)reinterpret_cast<structure
>(s
); // expected-error {{reinterpret_cast from 'structure' to 'structure' is not allowed}}
35 (void)reinterpret_cast<float>(f
); // expected-error {{reinterpret_cast from 'float' to 'float' is not allowed}}
38 // Test conversion between pointer and integral types, as in /3 and /4.
39 void integral_conversion()
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
);
49 void pointer_conversion()
52 float *p2
= reinterpret_cast<float*>(p1
);
53 structure
*p3
= reinterpret_cast<structure
*>(p2
);
55 ppint
*deep
= reinterpret_cast<ppint
*>(p3
);
56 (void)reinterpret_cast<fnptr
*>(deep
);
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}}
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
);
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.
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
);
88 typedef int (*fnptr2
)(int);
90 (void)reinterpret_cast<fnptr2
>(fp
);
91 void *vp
= reinterpret_cast<void*>(fp
);
92 (void)reinterpret_cast<fnptr
>(vp
);
98 char &c
= reinterpret_cast<char&>(l
);
100 (void)reinterpret_cast<int&>(&c
); // expected-error {{reinterpret_cast from rvalue to reference type 'int &'}}
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}}
109 void (structure::*psf
)() = 0;
110 (void)reinterpret_cast<int (structure::*)()>(psf
);
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}}
115 // Cannot cast from integers to member pointers, not even the null pointer
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}}
126 void (B::*b
)() = reinterpret_cast<void (B::*)()>(a
);
129 void const_arrays() {
130 typedef char STRING
[10];
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
);
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 &'}}
142 __attribute((ext_vector_type(4))) typedef float v4
;
143 float& w(v4
&a
) { return reinterpret_cast<float&>(a
[1]); } // expected-error {{not allowed}}
146 void dereference_reinterpret_cast() {
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}}
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
);
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
);
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
);
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
);
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 *'}}
223 void reinterpret_cast_allowlist () {
224 // the dynamic type of the object
227 (void)reinterpret_cast<int&>(a
);
228 (void)*reinterpret_cast<int*>(&a
);
229 (void)reinterpret_cast<float&>(b
);
230 (void)*reinterpret_cast<float*>(&b
);
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
);
246 // a type that is the signed or unsigned type corresponding to the dynamic
247 // type of the object
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
);
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
);
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
289 // TODO: checking is not implemented for tag types
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
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
);