blob: be960a3af8b54f89d2767f12fef11653f002a96c [file] [log] [blame]
Daniel Dunbard7d5f022009-03-24 02:24:46 +00001// RUN: clang-cc -fsyntax-only -verify %s
Douglas Gregor2f639b92008-10-24 15:36:09 +00002
3enum test { testval = 1 };
4struct structure { int m; };
5typedef void (*fnptr)();
6
7// Test the conversion to self.
8void self_conversion()
9{
10 // T*->T* is allowed, T->T in general not.
11 int i = 0;
12 (void)reinterpret_cast<int>(i); // expected-error {{reinterpret_cast from 'int' to 'int' is not allowed}}
13 structure s;
14 (void)reinterpret_cast<structure>(s); // expected-error {{reinterpret_cast from 'struct structure' to 'struct structure' is not allowed}}
15 int *pi = 0;
16 (void)reinterpret_cast<int*>(pi);
17}
18
19// Test conversion between pointer and integral types, as in /3 and /4.
20void integral_conversion()
21{
22 void *vp = reinterpret_cast<void*>(testval);
23 long l = reinterpret_cast<long>(vp);
24 (void)reinterpret_cast<float*>(l);
25 fnptr fnp = reinterpret_cast<fnptr>(l);
26 (void)reinterpret_cast<char>(fnp); // expected-error {{cast from pointer to smaller type 'char' loses information}}
27 (void)reinterpret_cast<long>(fnp);
28}
29
30void pointer_conversion()
31{
32 int *p1 = 0;
33 float *p2 = reinterpret_cast<float*>(p1);
34 structure *p3 = reinterpret_cast<structure*>(p2);
35 typedef int **ppint;
36 ppint *deep = reinterpret_cast<ppint*>(p3);
37 (void)reinterpret_cast<fnptr*>(deep);
38}
39
40void constness()
41{
42 int ***const ipppc = 0;
43 // Valid: T1* -> T2 const*
44 int const *icp = reinterpret_cast<int const*>(ipppc);
45 // Invalid: T1 const* -> T2*
46 (void)reinterpret_cast<int*>(icp); // expected-error {{reinterpret_cast from 'int const *' to 'int *' casts away constness}}
47 // Invalid: T1*** -> T2 const* const**
48 int const *const **icpcpp = reinterpret_cast<int const* const**>(ipppc); // expected-error {{reinterpret_cast from 'int ***const' to 'int const *const **' casts away constness}}
49 // Valid: T1* -> T2*
50 int *ip = reinterpret_cast<int*>(icpcpp);
51 // Valid: T* -> T const*
52 (void)reinterpret_cast<int const*>(ip);
53 // Valid: T*** -> T2 const* const* const*
54 (void)reinterpret_cast<int const* const* const*>(ipppc);
55}
56
57void fnptrs()
58{
59 typedef int (*fnptr2)(int);
60 fnptr fp = 0;
61 (void)reinterpret_cast<fnptr2>(fp);
62 void *vp = reinterpret_cast<void*>(fp);
63 (void)reinterpret_cast<fnptr>(vp);
64}
65
66void refs()
67{
68 long l = 0;
69 char &c = reinterpret_cast<char&>(l);
70 // Bad: from rvalue
71 (void)reinterpret_cast<int&>(&c); // expected-error {{reinterpret_cast from rvalue to reference type 'int &'}}
72}
Sebastian Redldb647282009-01-27 23:18:31 +000073
74void memptrs()
75{
76 const int structure::*psi = 0;
77 (void)reinterpret_cast<const float structure::*>(psi);
78 (void)reinterpret_cast<int structure::*>(psi); // expected-error {{reinterpret_cast from 'int const struct structure::*' to 'int struct structure::*' casts away constness}}
79
80 void (structure::*psf)() = 0;
81 (void)reinterpret_cast<int (structure::*)()>(psf);
82
Argyrios Kyrtzidis7c94c4b2009-06-03 02:06:50 +000083 (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error {{reinterpret_cast from 'int const struct structure::*' to 'void (struct structure::*)()' is not allowed}}
84 (void)reinterpret_cast<int structure::*>(psf); // expected-error {{reinterpret_cast from 'void (struct structure::*)()' to 'int struct structure::*' is not allowed}}
Sebastian Redldb647282009-01-27 23:18:31 +000085
86 // Cannot cast from integers to member pointers, not even the null pointer
87 // literal.
Argyrios Kyrtzidis7c94c4b2009-06-03 02:06:50 +000088 (void)reinterpret_cast<void (structure::*)()>(0); // expected-error {{reinterpret_cast from 'int' to 'void (struct structure::*)()' is not allowed}}
Sebastian Redldb647282009-01-27 23:18:31 +000089 (void)reinterpret_cast<int structure::*>(0); // expected-error {{reinterpret_cast from 'int' to 'int struct structure::*' is not allowed}}
90}
Sebastian Redl76d69bb2009-11-18 18:10:53 +000091
92// PR5545
93class A;
94class B;
95void (A::*a)();
96void (B::*b)() = reinterpret_cast<void (B::*)()>(a);