blob: fc7d15c8a344752168cf8ce7eb9e3ac5ba4b7b45 [file] [log] [blame]
John McCall437da052013-03-22 02:58:14 +00001// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s
2
3// PR 13824
4class A {
5};
6class DA : public A {
7};
8class DDA : public DA {
9};
10class DAo : protected A {
11};
12class DAi : private A {
13};
14
15class DVA : public virtual A {
16};
17class DDVA : public virtual DA {
18};
19class DMA : public virtual A, public virtual DA {
20};
21
22class B;
23
24struct C {
25 // Do not fail on incompletely-defined classes.
26 decltype(reinterpret_cast<C *>(0)) foo;
27 decltype(reinterpret_cast<A *>((C *) 0)) bar;
28 decltype(reinterpret_cast<C *>((A *) 0)) baz;
29};
30
31void reinterpret_not_defined_class(B *b, C *c) {
32 // Should not fail if class has no definition.
33 (void)*reinterpret_cast<C *>(b);
34 (void)*reinterpret_cast<B *>(c);
35
36 (void)reinterpret_cast<C &>(*b);
37 (void)reinterpret_cast<B &>(*c);
38}
39
40void reinterpret_not_updowncast(A *pa, const A *pca, A &a, const A &ca) {
41 (void)*reinterpret_cast<C *>(pa);
42 (void)*reinterpret_cast<const C *>(pa);
43 (void)*reinterpret_cast<volatile C *>(pa);
44 (void)*reinterpret_cast<const volatile C *>(pa);
45
46 (void)*reinterpret_cast<const C *>(pca);
47 (void)*reinterpret_cast<const volatile C *>(pca);
48
49 (void)reinterpret_cast<C &>(a);
50 (void)reinterpret_cast<const C &>(a);
51 (void)reinterpret_cast<volatile C &>(a);
52 (void)reinterpret_cast<const volatile C &>(a);
53
54 (void)reinterpret_cast<const C &>(ca);
55 (void)reinterpret_cast<const volatile C &>(ca);
56}
57
58void reinterpret_pointer_downcast(A *a, const A *ca) {
59 (void)*reinterpret_cast<DA *>(a);
60 (void)*reinterpret_cast<const DA *>(a);
61 (void)*reinterpret_cast<volatile DA *>(a);
62 (void)*reinterpret_cast<const volatile DA *>(a);
63
64 (void)*reinterpret_cast<const DA *>(ca);
65 (void)*reinterpret_cast<const volatile DA *>(ca);
66
67 (void)*reinterpret_cast<DDA *>(a);
68 (void)*reinterpret_cast<DAo *>(a);
69 (void)*reinterpret_cast<DAi *>(a);
70 // expected-warning@+2 {{'reinterpret_cast' to class 'DVA *' from its virtual base 'A *' behaves differently from 'static_cast'}}
71 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
72 (void)*reinterpret_cast<DVA *>(a);
73 // expected-warning@+2 {{'reinterpret_cast' to class 'DDVA *' from its virtual base 'A *' behaves differently from 'static_cast'}}
74 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
75 (void)*reinterpret_cast<DDVA *>(a);
76 // expected-warning@+2 {{'reinterpret_cast' to class 'DMA *' from its virtual base 'A *' behaves differently from 'static_cast'}}
77 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
78 (void)*reinterpret_cast<DMA *>(a);
79}
80
81void reinterpret_reference_downcast(A a, A &ra, const A &cra) {
82 (void)reinterpret_cast<DA &>(a);
83 (void)reinterpret_cast<const DA &>(a);
84 (void)reinterpret_cast<volatile DA &>(a);
85 (void)reinterpret_cast<const volatile DA &>(a);
86
87 (void)reinterpret_cast<DA &>(ra);
88 (void)reinterpret_cast<const DA &>(ra);
89 (void)reinterpret_cast<volatile DA &>(ra);
90 (void)reinterpret_cast<const volatile DA &>(ra);
91
92 (void)reinterpret_cast<const DA &>(cra);
93 (void)reinterpret_cast<const volatile DA &>(cra);
94
95 (void)reinterpret_cast<DDA &>(a);
96 (void)reinterpret_cast<DAo &>(a);
97 (void)reinterpret_cast<DAi &>(a);
98 // expected-warning@+2 {{'reinterpret_cast' to class 'DVA &' from its virtual base 'A' behaves differently from 'static_cast'}}
99 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
100 (void)reinterpret_cast<DVA &>(a);
101 // expected-warning@+2 {{'reinterpret_cast' to class 'DDVA &' from its virtual base 'A' behaves differently from 'static_cast'}}
102 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
103 (void)reinterpret_cast<DDVA &>(a);
104 // expected-warning@+2 {{'reinterpret_cast' to class 'DMA &' from its virtual base 'A' behaves differently from 'static_cast'}}
105 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
106 (void)reinterpret_cast<DMA &>(a);
107}
108
109void reinterpret_pointer_upcast(DA *da, const DA *cda, DDA *dda, DAo *dao,
110 DAi *dai, DVA *dva, DDVA *ddva, DMA *dma) {
111 (void)*reinterpret_cast<A *>(da);
112 (void)*reinterpret_cast<const A *>(da);
113 (void)*reinterpret_cast<volatile A *>(da);
114 (void)*reinterpret_cast<const volatile A *>(da);
115
116 (void)*reinterpret_cast<const A *>(cda);
117 (void)*reinterpret_cast<const volatile A *>(cda);
118
119 (void)*reinterpret_cast<A *>(dda);
120 (void)*reinterpret_cast<DA *>(dda);
121 (void)*reinterpret_cast<A *>(dao);
122 (void)*reinterpret_cast<A *>(dai);
123 // expected-warning@+2 {{'reinterpret_cast' from class 'DVA *' to its virtual base 'A *' behaves differently from 'static_cast'}}
124 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
125 (void)*reinterpret_cast<A *>(dva);
126 // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA *' to its virtual base 'A *' behaves differently from 'static_cast'}}
127 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
128 (void)*reinterpret_cast<A *>(ddva);
129 // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA *' to its virtual base 'DA *' behaves differently from 'static_cast'}}
130 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
131 (void)*reinterpret_cast<DA *>(ddva);
132 // expected-warning@+2 {{'reinterpret_cast' from class 'DMA *' to its virtual base 'A *' behaves differently from 'static_cast'}}
133 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
134 (void)*reinterpret_cast<A *>(dma);
135 // expected-warning@+2 {{'reinterpret_cast' from class 'DMA *' to its virtual base 'DA *' behaves differently from 'static_cast'}}
136 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
137 (void)*reinterpret_cast<DA *>(dma);
138}
139
140void reinterpret_reference_upcast(DA &da, const DA &cda, DDA &dda, DAo &dao,
141 DAi &dai, DVA &dva, DDVA &ddva, DMA &dma) {
142 (void)reinterpret_cast<A &>(da);
143 (void)reinterpret_cast<const A &>(da);
144 (void)reinterpret_cast<volatile A &>(da);
145 (void)reinterpret_cast<const volatile A &>(da);
146
147 (void)reinterpret_cast<const A &>(cda);
148 (void)reinterpret_cast<const volatile A &>(cda);
149
150 (void)reinterpret_cast<A &>(dda);
151 (void)reinterpret_cast<DA &>(dda);
152 (void)reinterpret_cast<A &>(dao);
153 (void)reinterpret_cast<A &>(dai);
154 // expected-warning@+2 {{'reinterpret_cast' from class 'DVA' to its virtual base 'A &' behaves differently from 'static_cast'}}
155 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
156 (void)reinterpret_cast<A &>(dva);
157 // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA' to its virtual base 'A &' behaves differently from 'static_cast'}}
158 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
159 (void)reinterpret_cast<A &>(ddva);
160 // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA' to its virtual base 'DA &' behaves differently from 'static_cast'}}
161 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
162 (void)reinterpret_cast<DA &>(ddva);
163 // expected-warning@+2 {{'reinterpret_cast' from class 'DMA' to its virtual base 'A &' behaves differently from 'static_cast'}}
164 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
165 (void)reinterpret_cast<A &>(dma);
166 // expected-warning@+2 {{'reinterpret_cast' from class 'DMA' to its virtual base 'DA &' behaves differently from 'static_cast'}}
167 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
168 (void)reinterpret_cast<DA &>(dma);
169}
170
171struct E {
172 int x;
173};
174
175class F : public E {
176 virtual int foo() { return x; }
177};
178
179class G : public F {
180};
181
182class H : public E, public A {
183};
184
185class I : virtual public F {
186};
187
188typedef const F * K;
189typedef volatile K L;
190
191void different_subobject_downcast(E *e, F *f, A *a) {
192 // expected-warning@+2 {{'reinterpret_cast' to class 'F *' from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
193 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
194 (void)reinterpret_cast<F *>(e);
195 // expected-warning@+2 {{'reinterpret_cast' to class 'G *' from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
196 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
197 (void)reinterpret_cast<G *>(e);
198 (void)reinterpret_cast<H *>(e);
199 // expected-warning@+2 {{'reinterpret_cast' to class 'I *' from its virtual base 'E *' behaves differently from 'static_cast'}}
200 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
201 (void)reinterpret_cast<I *>(e);
202
203 (void)reinterpret_cast<G *>(f);
204 // expected-warning@+2 {{'reinterpret_cast' to class 'I *' from its virtual base 'F *' behaves differently from 'static_cast'}}
205 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
206 (void)reinterpret_cast<I *>(f);
207
208 (void)reinterpret_cast<H *>(a);
209
210 // expected-warning@+2 {{'reinterpret_cast' to class 'L' (aka 'const F *volatile') from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
211 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
212 (void)reinterpret_cast<L>(e);
213}
214
215void different_subobject_upcast(F *f, G *g, H *h, I *i) {
216 // expected-warning@+2 {{'reinterpret_cast' from class 'F *' to its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
217 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
218 (void)reinterpret_cast<E *>(f);
219
220 (void)reinterpret_cast<F *>(g);
221 // expected-warning@+2 {{'reinterpret_cast' from class 'G *' to its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
222 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
223 (void)reinterpret_cast<E *>(g);
224
225 (void)reinterpret_cast<E *>(h);
226 (void)reinterpret_cast<A *>(h);
227
228 // expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'F *' behaves differently from 'static_cast'}}
229 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
230 (void)reinterpret_cast<F *>(i);
231 // expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'E *' behaves differently from 'static_cast'}}
232 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
233 (void)reinterpret_cast<E *>(i);
234}