1// RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding -Wundefined-reinterpret-cast -Wno-unused-volatile-lvalue %s
2
3#include <stdint.h>
4
5enum 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 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.
36void 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
46void 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
56void 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
73void 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
82void 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
90void 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
108namespace PR5545 {
109// PR5545
110class A;
111class B;
112void (A::*a)();
113void (B::*b)() = reinterpret_cast<void (B::*)()>(a);
114}
115
116// <rdar://problem/8018292>
117void 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
126namespace 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
134void 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
211void 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