1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s
2 // RUN: not %clang_cc1 -std=c++11 -fsyntax-only -fdiagnostics-parseable-fixits -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s 2>&1 | FileCheck %s
3 
4 // PR 13824
5 class A {
6 };
7 class DA : public A {
8 };
9 class DDA : public DA {
10 };
11 class DAo : protected A {
12 };
13 class DAi : private A {
14 };
15 
16 class DVA : public virtual A {
17 };
18 class DDVA : public virtual DA {
19 };
20 class DMA : public virtual A, public virtual DA {
21 };
22 
23 class B;
24 
25 struct C {
26   // Do not fail on incompletely-defined classes.
27   decltype(reinterpret_cast<C *>(0)) foo;
28   decltype(reinterpret_cast<A *>((C *) 0)) bar;
29   decltype(reinterpret_cast<C *>((A *) 0)) baz;
30 };
31 
32 void reinterpret_not_defined_class(B *b, C *c) {
33   // Should not fail if class has no definition.
34   (void)*reinterpret_cast<C *>(b);
35   (void)*reinterpret_cast<B *>(c);
36 
37   (void)reinterpret_cast<C &>(*b);
38   (void)reinterpret_cast<B &>(*c);
39 }
40 
41 // Do not fail on erroneous classes with fields of incompletely-defined types.
42 // Base class is malformed.
43 namespace BaseMalformed {
44   struct A; // expected-note {{forward declaration of 'BaseMalformed::A'}}
45   struct B {
46     A a; // expected-error {{field has incomplete type 'BaseMalformed::A'}}
47   };
48   struct C : public B {} c;
49   B *b = reinterpret_cast<B *>(&c);
50 } // end anonymous namespace
51 
52 // Child class is malformed.
53 namespace ChildMalformed {
54   struct A; // expected-note {{forward declaration of 'ChildMalformed::A'}}
55   struct B {};
56   struct C : public B {
57     A a; // expected-error {{field has incomplete type 'ChildMalformed::A'}}
58   } c;
59   B *b = reinterpret_cast<B *>(&c);
60 } // end anonymous namespace
61 
62 // Base class outside upcast base-chain is malformed.
63 namespace BaseBaseMalformed {
64   struct A; // expected-note {{forward declaration of 'BaseBaseMalformed::A'}}
65   struct Y {};
66   struct X { A a; }; // expected-error {{field has incomplete type 'BaseBaseMalformed::A'}}
67   struct B : Y, X {};
68   struct C : B {} c;
69   B *p = reinterpret_cast<B*>(&c);
70 }
71 
72 namespace InheritanceMalformed {
73   struct A; // expected-note {{forward declaration of 'InheritanceMalformed::A'}}
74   struct B : A {}; // expected-error {{base class has incomplete type}}
75   struct C : B {} c;
76   B *p = reinterpret_cast<B*>(&c);
77 }
78 
79 // Virtual base class outside upcast base-chain is malformed.
80 namespace VBaseMalformed{
81   struct A; // expected-note {{forward declaration of 'VBaseMalformed::A'}}
82   struct X { A a; };  // expected-error {{field has incomplete type 'VBaseMalformed::A'}}
83   struct B : public virtual X {};
84   struct C : B {} c;
85   B *p = reinterpret_cast<B*>(&c);
86 }
87 
88 void reinterpret_not_updowncast(A *pa, const A *pca, A &a, const A &ca) {
89   (void)*reinterpret_cast<C *>(pa);
90   (void)*reinterpret_cast<const C *>(pa);
91   (void)*reinterpret_cast<volatile C *>(pa);
92   (void)*reinterpret_cast<const volatile C *>(pa);
93 
94   (void)*reinterpret_cast<const C *>(pca);
95   (void)*reinterpret_cast<const volatile C *>(pca);
96 
97   (void)reinterpret_cast<C &>(a);
98   (void)reinterpret_cast<const C &>(a);
99   (void)reinterpret_cast<volatile C &>(a);
100   (void)reinterpret_cast<const volatile C &>(a);
101 
102   (void)reinterpret_cast<const C &>(ca);
103   (void)reinterpret_cast<const volatile C &>(ca);
104 }
105 
106 void reinterpret_pointer_downcast(A *a, const A *ca) {
107   (void)*reinterpret_cast<DA *>(a);
108   (void)*reinterpret_cast<const DA *>(a);
109   (void)*reinterpret_cast<volatile DA *>(a);
110   (void)*reinterpret_cast<const volatile DA *>(a);
111 
112   (void)*reinterpret_cast<const DA *>(ca);
113   (void)*reinterpret_cast<const volatile DA *>(ca);
114 
115   (void)*reinterpret_cast<DDA *>(a);
116   (void)*reinterpret_cast<DAo *>(a);
117   (void)*reinterpret_cast<DAi *>(a);
118   // expected-warning@+2 {{'reinterpret_cast' to class 'DVA *' from its virtual base 'A *' behaves differently from 'static_cast'}}
119   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
120   (void)*reinterpret_cast<DVA *>(a);
121   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
122 
123   // expected-warning@+2 {{'reinterpret_cast' to class 'DDVA *' from its virtual base 'A *' behaves differently from 'static_cast'}}
124   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
125   (void)*reinterpret_cast<DDVA *>(a);
126   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
127 
128   // expected-warning@+2 {{'reinterpret_cast' to class 'DMA *' from its virtual base 'A *' behaves differently from 'static_cast'}}
129   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
130   (void)*reinterpret_cast<DMA *>(a);
131   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
132 }
133 
134 void reinterpret_reference_downcast(A a, A &ra, const A &cra) {
135   (void)reinterpret_cast<DA &>(a);
136   (void)reinterpret_cast<const DA &>(a);
137   (void)reinterpret_cast<volatile DA &>(a);
138   (void)reinterpret_cast<const volatile DA &>(a);
139 
140   (void)reinterpret_cast<DA &>(ra);
141   (void)reinterpret_cast<const DA &>(ra);
142   (void)reinterpret_cast<volatile DA &>(ra);
143   (void)reinterpret_cast<const volatile DA &>(ra);
144 
145   (void)reinterpret_cast<const DA &>(cra);
146   (void)reinterpret_cast<const volatile DA &>(cra);
147 
148   (void)reinterpret_cast<DDA &>(a);
149   (void)reinterpret_cast<DAo &>(a);
150   (void)reinterpret_cast<DAi &>(a);
151   // expected-warning@+2 {{'reinterpret_cast' to class 'DVA &' from its virtual base 'A' behaves differently from 'static_cast'}}
152   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
153   (void)reinterpret_cast<DVA &>(a);
154   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
155 
156   // expected-warning@+2 {{'reinterpret_cast' to class 'DDVA &' from its virtual base 'A' behaves differently from 'static_cast'}}
157   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
158   (void)reinterpret_cast<DDVA &>(a);
159   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
160 
161   // expected-warning@+2 {{'reinterpret_cast' to class 'DMA &' from its virtual base 'A' behaves differently from 'static_cast'}}
162   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
163   (void)reinterpret_cast<DMA &>(a);
164   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
165 }
166 
167 void reinterpret_pointer_upcast(DA *da, const DA *cda, DDA *dda, DAo *dao,
168                                 DAi *dai, DVA *dva, DDVA *ddva, DMA *dma) {
169   (void)*reinterpret_cast<A *>(da);
170   (void)*reinterpret_cast<const A *>(da);
171   (void)*reinterpret_cast<volatile A *>(da);
172   (void)*reinterpret_cast<const volatile A *>(da);
173 
174   (void)*reinterpret_cast<const A *>(cda);
175   (void)*reinterpret_cast<const volatile A *>(cda);
176 
177   (void)*reinterpret_cast<A *>(dda);
178   (void)*reinterpret_cast<DA *>(dda);
179   (void)*reinterpret_cast<A *>(dao);
180   (void)*reinterpret_cast<A *>(dai);
181   // expected-warning@+2 {{'reinterpret_cast' from class 'DVA *' to its virtual base 'A *' behaves differently from 'static_cast'}}
182   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
183   (void)*reinterpret_cast<A *>(dva);
184   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
185 
186   // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA *' to its virtual base 'A *' behaves differently from 'static_cast'}}
187   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
188   (void)*reinterpret_cast<A *>(ddva);
189   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
190 
191   // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA *' to its virtual base 'DA *' behaves differently from 'static_cast'}}
192   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
193   (void)*reinterpret_cast<DA *>(ddva);
194   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
195 
196   // expected-warning@+2 {{'reinterpret_cast' from class 'DMA *' to its virtual base 'A *' behaves differently from 'static_cast'}}
197   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
198   (void)*reinterpret_cast<A *>(dma);
199   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
200 
201   // expected-warning@+2 {{'reinterpret_cast' from class 'DMA *' to its virtual base 'DA *' behaves differently from 'static_cast'}}
202   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
203   (void)*reinterpret_cast<DA *>(dma);
204   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
205 }
206 
207 void reinterpret_reference_upcast(DA &da, const DA &cda, DDA &dda, DAo &dao,
208                                   DAi &dai, DVA &dva, DDVA &ddva, DMA &dma) {
209   (void)reinterpret_cast<A &>(da);
210   (void)reinterpret_cast<const A &>(da);
211   (void)reinterpret_cast<volatile A &>(da);
212   (void)reinterpret_cast<const volatile A &>(da);
213 
214   (void)reinterpret_cast<const A &>(cda);
215   (void)reinterpret_cast<const volatile A &>(cda);
216 
217   (void)reinterpret_cast<A &>(dda);
218   (void)reinterpret_cast<DA &>(dda);
219   (void)reinterpret_cast<A &>(dao);
220   (void)reinterpret_cast<A &>(dai);
221   // expected-warning@+2 {{'reinterpret_cast' from class 'DVA' to its virtual base 'A &' behaves differently from 'static_cast'}}
222   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
223   (void)reinterpret_cast<A &>(dva);
224   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
225 
226   // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA' to its virtual base 'A &' behaves differently from 'static_cast'}}
227   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
228   (void)reinterpret_cast<A &>(ddva);
229   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
230 
231   // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA' to its virtual base 'DA &' behaves differently from 'static_cast'}}
232   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
233   (void)reinterpret_cast<DA &>(ddva);
234   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
235 
236   // expected-warning@+2 {{'reinterpret_cast' from class 'DMA' to its virtual base 'A &' behaves differently from 'static_cast'}}
237   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
238   (void)reinterpret_cast<A &>(dma);
239   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
240 
241   // expected-warning@+2 {{'reinterpret_cast' from class 'DMA' to its virtual base 'DA &' behaves differently from 'static_cast'}}
242   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
243   (void)reinterpret_cast<DA &>(dma);
244   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
245 }
246 
247 struct E {
248   int x;
249 };
250 
251 class F : public E {
252   virtual int foo() { return x; }
253 };
254 
255 class G : public F {
256 };
257 
258 class H : public E, public A {
259 };
260 
261 class I : virtual public F {
262 };
263 
264 typedef const F * K;
265 typedef volatile K L;
266 
267 void different_subobject_downcast(E *e, F *f, A *a) {
268   // expected-warning@+2 {{'reinterpret_cast' to class 'F *' from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
269   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
270   (void)reinterpret_cast<F *>(e);
271   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
272 
273   // expected-warning@+2 {{'reinterpret_cast' to class 'G *' from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
274   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
275   (void)reinterpret_cast<G *>(e);
276   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
277 
278   (void)reinterpret_cast<H *>(e);
279   // expected-warning@+2 {{'reinterpret_cast' to class 'I *' from its virtual base 'E *' behaves differently from 'static_cast'}}
280   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
281   (void)reinterpret_cast<I *>(e);
282   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
283 
284 
285   (void)reinterpret_cast<G *>(f);
286   // expected-warning@+2 {{'reinterpret_cast' to class 'I *' from its virtual base 'F *' behaves differently from 'static_cast'}}
287   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
288   (void)reinterpret_cast<I *>(f);
289   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
290 
291   (void)reinterpret_cast<H *>(a);
292 
293   // 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'}}
294   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
295   (void)reinterpret_cast<L>(e);
296   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
297 }
298 
299 void different_subobject_upcast(F *f, G *g, H *h, I *i) {
300   // expected-warning@+2 {{'reinterpret_cast' from class 'F *' to its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
301   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
302   (void)reinterpret_cast<E *>(f);
303   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
304 
305   (void)reinterpret_cast<F *>(g);
306   // expected-warning@+2 {{'reinterpret_cast' from class 'G *' to its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
307   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
308   (void)reinterpret_cast<E *>(g);
309   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
310 
311   (void)reinterpret_cast<E *>(h);
312   (void)reinterpret_cast<A *>(h);
313 
314   // expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'F *' behaves differently from 'static_cast'}}
315   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
316   (void)reinterpret_cast<F *>(i);
317   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
318 
319   // expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'E *' behaves differently from 'static_cast'}}
320   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
321   (void)reinterpret_cast<E *>(i);
322   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
323 }
324