blob: 68005a5270e41a7e775f4a803d4c5c3ffa1e114f [file] [log] [blame]
Argyrios Kyrtzidisf4bbbf02011-05-02 18:21:19 +00001// RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding -Wundefined-reinterpret-cast %s
Douglas Gregor2f639b92008-10-24 15:36:09 +00002
Sean Huntf1cd5e52009-11-22 07:05:50 +00003#include <stdint.h>
4
Douglas Gregor2f639b92008-10-24 15:36:09 +00005enum test { testval = 1 };
6struct structure { int m; };
7typedef void (*fnptr)();
8
9// Test the conversion to self.
10void self_conversion()
11{
12 // T*->T* is allowed, T->T in general not.
13 int i = 0;
14 (void)reinterpret_cast<int>(i); // expected-error {{reinterpret_cast from 'int' to 'int' is not allowed}}
15 structure s;
John McCall7c2342d2010-03-10 11:27:22 +000016 (void)reinterpret_cast<structure>(s); // expected-error {{reinterpret_cast from 'structure' to 'structure' is not allowed}}
Douglas Gregor2f639b92008-10-24 15:36:09 +000017 int *pi = 0;
18 (void)reinterpret_cast<int*>(pi);
19}
20
21// Test conversion between pointer and integral types, as in /3 and /4.
22void integral_conversion()
23{
24 void *vp = reinterpret_cast<void*>(testval);
Sean Huntf1cd5e52009-11-22 07:05:50 +000025 intptr_t i = reinterpret_cast<intptr_t>(vp);
26 (void)reinterpret_cast<float*>(i);
27 fnptr fnp = reinterpret_cast<fnptr>(i);
Douglas Gregor2f639b92008-10-24 15:36:09 +000028 (void)reinterpret_cast<char>(fnp); // expected-error {{cast from pointer to smaller type 'char' loses information}}
Sean Huntf1cd5e52009-11-22 07:05:50 +000029 (void)reinterpret_cast<intptr_t>(fnp);
Douglas Gregor2f639b92008-10-24 15:36:09 +000030}
31
32void pointer_conversion()
33{
34 int *p1 = 0;
35 float *p2 = reinterpret_cast<float*>(p1);
36 structure *p3 = reinterpret_cast<structure*>(p2);
37 typedef int **ppint;
38 ppint *deep = reinterpret_cast<ppint*>(p3);
39 (void)reinterpret_cast<fnptr*>(deep);
40}
41
42void constness()
43{
44 int ***const ipppc = 0;
45 // Valid: T1* -> T2 const*
46 int const *icp = reinterpret_cast<int const*>(ipppc);
47 // Invalid: T1 const* -> T2*
Douglas Gregord4c5f842011-04-15 17:59:54 +000048 (void)reinterpret_cast<int*>(icp); // expected-error {{reinterpret_cast from 'const int *' to 'int *' casts away qualifiers}}
Douglas Gregor2f639b92008-10-24 15:36:09 +000049 // Invalid: T1*** -> T2 const* const**
Douglas Gregord4c5f842011-04-15 17:59:54 +000050 int const *const **icpcpp = reinterpret_cast<int const* const**>(ipppc); // expected-error {{reinterpret_cast from 'int ***' to 'const int *const **' casts away qualifiers}}
Douglas Gregor2f639b92008-10-24 15:36:09 +000051 // Valid: T1* -> T2*
52 int *ip = reinterpret_cast<int*>(icpcpp);
53 // Valid: T* -> T const*
54 (void)reinterpret_cast<int const*>(ip);
55 // Valid: T*** -> T2 const* const* const*
56 (void)reinterpret_cast<int const* const* const*>(ipppc);
57}
58
59void fnptrs()
60{
61 typedef int (*fnptr2)(int);
62 fnptr fp = 0;
63 (void)reinterpret_cast<fnptr2>(fp);
64 void *vp = reinterpret_cast<void*>(fp);
65 (void)reinterpret_cast<fnptr>(vp);
66}
67
68void refs()
69{
70 long l = 0;
71 char &c = reinterpret_cast<char&>(l);
72 // Bad: from rvalue
73 (void)reinterpret_cast<int&>(&c); // expected-error {{reinterpret_cast from rvalue to reference type 'int &'}}
74}
Sebastian Redldb647282009-01-27 23:18:31 +000075
76void memptrs()
77{
78 const int structure::*psi = 0;
79 (void)reinterpret_cast<const float structure::*>(psi);
Douglas Gregord4c5f842011-04-15 17:59:54 +000080 (void)reinterpret_cast<int structure::*>(psi); // expected-error {{reinterpret_cast from 'const int structure::*' to 'int structure::*' casts away qualifiers}}
Sebastian Redldb647282009-01-27 23:18:31 +000081
82 void (structure::*psf)() = 0;
83 (void)reinterpret_cast<int (structure::*)()>(psf);
84
Chris Lattner58f9e132010-09-05 00:04:01 +000085 (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error {{reinterpret_cast from 'const int structure::*' to 'void (structure::*)()' is not allowed}}
John McCall7c2342d2010-03-10 11:27:22 +000086 (void)reinterpret_cast<int structure::*>(psf); // expected-error {{reinterpret_cast from 'void (structure::*)()' to 'int structure::*' is not allowed}}
Sebastian Redldb647282009-01-27 23:18:31 +000087
88 // Cannot cast from integers to member pointers, not even the null pointer
89 // literal.
John McCall7c2342d2010-03-10 11:27:22 +000090 (void)reinterpret_cast<void (structure::*)()>(0); // expected-error {{reinterpret_cast from 'int' to 'void (structure::*)()' is not allowed}}
91 (void)reinterpret_cast<int structure::*>(0); // expected-error {{reinterpret_cast from 'int' to 'int structure::*' is not allowed}}
Sebastian Redldb647282009-01-27 23:18:31 +000092}
Sebastian Redl76d69bb2009-11-18 18:10:53 +000093
Anders Carlsson52647c62010-06-04 22:47:55 +000094namespace PR5545 {
Sebastian Redl76d69bb2009-11-18 18:10:53 +000095// PR5545
96class A;
97class B;
98void (A::*a)();
99void (B::*b)() = reinterpret_cast<void (B::*)()>(a);
Anders Carlsson52647c62010-06-04 22:47:55 +0000100}
101
102// <rdar://problem/8018292>
103void const_arrays() {
104 typedef char STRING[10];
105 const STRING *s;
106 const char *c;
107
Douglas Gregord4c5f842011-04-15 17:59:54 +0000108 (void)reinterpret_cast<char *>(s); // expected-error {{reinterpret_cast from 'const STRING *' (aka 'char const (*)[10]') to 'char *' casts away qualifiers}}
Anders Carlsson52647c62010-06-04 22:47:55 +0000109 (void)reinterpret_cast<const STRING *>(c);
110}
Argyrios Kyrtzidisb464a5b2011-04-22 22:31:13 +0000111
112namespace PR9564 {
113 struct a { int a : 10; }; a x;
Argyrios Kyrtzidisbb29d1b2011-04-22 23:57:57 +0000114 int *y = &reinterpret_cast<int&>(x.a); // expected-error {{not allowed}}
115
116 __attribute((ext_vector_type(4))) typedef float v4;
117 float& w(v4 &a) { return reinterpret_cast<float&>(a[1]); } // expected-error {{not allowed}}
Argyrios Kyrtzidisb464a5b2011-04-22 22:31:13 +0000118}
Argyrios Kyrtzidisf4bbbf02011-05-02 18:21:19 +0000119
120void dereference_reinterpret_cast() {
121 struct A {};
Chandler Carruth1f8f2d52011-05-24 07:43:19 +0000122 typedef A A2;
Argyrios Kyrtzidisf4bbbf02011-05-02 18:21:19 +0000123 class B {};
Chandler Carruth1f8f2d52011-05-24 07:43:19 +0000124 typedef B B2;
Argyrios Kyrtzidisf4bbbf02011-05-02 18:21:19 +0000125 A a;
126 B b;
Chandler Carruth1f8f2d52011-05-24 07:43:19 +0000127 A2 a2;
128 B2 b2;
Argyrios Kyrtzidisf4bbbf02011-05-02 18:21:19 +0000129 long l;
130 double d;
131 float f;
132 char c;
133 unsigned char uc;
134 void* v_ptr;
135 (void)reinterpret_cast<double&>(l); // expected-warning {{reinterpret_cast from 'long' to 'double &' has undefined behavior}}
136 (void)*reinterpret_cast<double*>(&l); // expected-warning {{dereference of type 'double *' that was reinterpret_cast from type 'long *' has undefined behavior}}
137 (void)reinterpret_cast<double&>(f); // expected-warning {{reinterpret_cast from 'float' to 'double &' has undefined behavior}}
138 (void)*reinterpret_cast<double*>(&f); // expected-warning {{dereference of type 'double *' that was reinterpret_cast from type 'float *' has undefined behavior}}
139 (void)reinterpret_cast<float&>(l); // expected-warning {{reinterpret_cast from 'long' to 'float &' has undefined behavior}}
140 (void)*reinterpret_cast<float*>(&l); // expected-warning {{dereference of type 'float *' that was reinterpret_cast from type 'long *' has undefined behavior}}
141 (void)reinterpret_cast<float&>(d); // expected-warning {{reinterpret_cast from 'double' to 'float &' has undefined behavior}}
142 (void)*reinterpret_cast<float*>(&d); // expected-warning {{dereference of type 'float *' that was reinterpret_cast from type 'double *' has undefined behavior}}
143
144 // TODO: add warning for tag types
145 (void)reinterpret_cast<A&>(b);
146 (void)*reinterpret_cast<A*>(&b);
147 (void)reinterpret_cast<B&>(a);
148 (void)*reinterpret_cast<B*>(&a);
Chandler Carruth1f8f2d52011-05-24 07:43:19 +0000149 (void)reinterpret_cast<A2&>(b2);
150 (void)*reinterpret_cast<A2*>(&b2);
151 (void)reinterpret_cast<B2&>(a2);
152 (void)*reinterpret_cast<B2*>(&a2);
Argyrios Kyrtzidisf4bbbf02011-05-02 18:21:19 +0000153
154 // Casting to itself is allowed
155 (void)reinterpret_cast<A&>(a);
156 (void)*reinterpret_cast<A*>(&a);
157 (void)reinterpret_cast<B&>(b);
158 (void)*reinterpret_cast<B*>(&b);
159 (void)reinterpret_cast<long&>(l);
160 (void)*reinterpret_cast<long*>(&l);
161 (void)reinterpret_cast<double&>(d);
162 (void)*reinterpret_cast<double*>(&d);
163 (void)reinterpret_cast<char&>(c);
164 (void)*reinterpret_cast<char*>(&c);
165
166 // Casting to and from chars are allowable
167 (void)reinterpret_cast<A&>(c);
168 (void)*reinterpret_cast<A*>(&c);
169 (void)reinterpret_cast<B&>(c);
170 (void)*reinterpret_cast<B*>(&c);
171 (void)reinterpret_cast<long&>(c);
172 (void)*reinterpret_cast<long*>(&c);
173 (void)reinterpret_cast<double&>(c);
174 (void)*reinterpret_cast<double*>(&c);
175 (void)reinterpret_cast<char&>(l);
176 (void)*reinterpret_cast<char*>(&l);
177 (void)reinterpret_cast<char&>(d);
178 (void)*reinterpret_cast<char*>(&d);
179 (void)reinterpret_cast<char&>(f);
180 (void)*reinterpret_cast<char*>(&f);
181
182 // Casting from void pointer.
183 (void)*reinterpret_cast<A*>(v_ptr);
184 (void)*reinterpret_cast<B*>(v_ptr);
185 (void)*reinterpret_cast<long*>(v_ptr);
186 (void)*reinterpret_cast<double*>(v_ptr);
187 (void)*reinterpret_cast<float*>(v_ptr);
188
189 // Casting to void pointer
190 (void)*reinterpret_cast<void*>(&a);
191 (void)*reinterpret_cast<void*>(&b);
192 (void)*reinterpret_cast<void*>(&l);
193 (void)*reinterpret_cast<void*>(&d);
194 (void)*reinterpret_cast<void*>(&f);
195}
196
197void reinterpret_cast_whitelist () {
198 // the dynamic type of the object
199 int a;
200 float b;
201 (void)reinterpret_cast<int&>(a);
202 (void)*reinterpret_cast<int*>(&a);
203 (void)reinterpret_cast<float&>(b);
204 (void)*reinterpret_cast<float*>(&b);
205
206 // a cv-qualified version of the dynamic object
207 (void)reinterpret_cast<const int&>(a);
208 (void)*reinterpret_cast<const int*>(&a);
209 (void)reinterpret_cast<volatile int&>(a);
210 (void)*reinterpret_cast<volatile int*>(&a);
211 (void)reinterpret_cast<const volatile int&>(a);
212 (void)*reinterpret_cast<const volatile int*>(&a);
213 (void)reinterpret_cast<const float&>(b);
214 (void)*reinterpret_cast<const float*>(&b);
215 (void)reinterpret_cast<volatile float&>(b);
216 (void)*reinterpret_cast<volatile float*>(&b);
217 (void)reinterpret_cast<const volatile float&>(b);
218 (void)*reinterpret_cast<const volatile float*>(&b);
219
220 // a type that is the signed or unsigned type corresponding to the dynamic
221 // type of the object
222 signed d;
223 unsigned e;
224 (void)reinterpret_cast<signed&>(d);
225 (void)*reinterpret_cast<signed*>(&d);
226 (void)reinterpret_cast<signed&>(e);
227 (void)*reinterpret_cast<signed*>(&e);
228 (void)reinterpret_cast<unsigned&>(d);
229 (void)*reinterpret_cast<unsigned*>(&d);
230 (void)reinterpret_cast<unsigned&>(e);
231 (void)*reinterpret_cast<unsigned*>(&e);
232
233 // a type that is the signed or unsigned type corresponding a cv-qualified
234 // version of the dynamic type the object
235 (void)reinterpret_cast<const signed&>(d);
236 (void)*reinterpret_cast<const signed*>(&d);
237 (void)reinterpret_cast<const signed&>(e);
238 (void)*reinterpret_cast<const signed*>(&e);
239 (void)reinterpret_cast<const unsigned&>(d);
240 (void)*reinterpret_cast<const unsigned*>(&d);
241 (void)reinterpret_cast<const unsigned&>(e);
242 (void)*reinterpret_cast<const unsigned*>(&e);
243 (void)reinterpret_cast<volatile signed&>(d);
244 (void)*reinterpret_cast<volatile signed*>(&d);
245 (void)reinterpret_cast<volatile signed&>(e);
246 (void)*reinterpret_cast<volatile signed*>(&e);
247 (void)reinterpret_cast<volatile unsigned&>(d);
248 (void)*reinterpret_cast<volatile unsigned*>(&d);
249 (void)reinterpret_cast<volatile unsigned&>(e);
250 (void)*reinterpret_cast<volatile unsigned*>(&e);
251 (void)reinterpret_cast<const volatile signed&>(d);
252 (void)*reinterpret_cast<const volatile signed*>(&d);
253 (void)reinterpret_cast<const volatile signed&>(e);
254 (void)*reinterpret_cast<const volatile signed*>(&e);
255 (void)reinterpret_cast<const volatile unsigned&>(d);
256 (void)*reinterpret_cast<const volatile unsigned*>(&d);
257 (void)reinterpret_cast<const volatile unsigned&>(e);
258 (void)*reinterpret_cast<const volatile unsigned*>(&e);
259
260 // an aggregate or union type that includes one of the aforementioned types
261 // among its members (including, recursively, a member of a subaggregate or
262 // contained union)
263 // TODO: checking is not implemented for tag types
264
265 // a type that is a (possible cv-qualified) base class type of the dynamic
266 // type of the object
267 // TODO: checking is not implemented for tag types
268
269 // a char or unsigned char type
270 (void)reinterpret_cast<char&>(a);
271 (void)*reinterpret_cast<char*>(&a);
272 (void)reinterpret_cast<unsigned char&>(a);
273 (void)*reinterpret_cast<unsigned char*>(&a);
274 (void)reinterpret_cast<char&>(b);
275 (void)*reinterpret_cast<char*>(&b);
276 (void)reinterpret_cast<unsigned char&>(b);
277 (void)*reinterpret_cast<unsigned char*>(&b);
278}