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