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