1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -triple %itanium_abi_triple -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s
2 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s
4 // 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 // 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
12 class DDA
: public DA
{
14 class DAo
: protected A
{
16 class DAi
: private A
{
19 class DVA
: public virtual A
{
21 class DDVA
: public virtual DA
{
23 class DMA
: public virtual A
, public virtual DA
{ //expected-warning{{direct base 'A' is inaccessible due to ambiguity:\n class DMA -> A\n class DMA -> DA -> A}}
29 // Do not fail on incompletely-defined classes.
30 decltype(reinterpret_cast<C
*>(0)) foo
;
31 decltype(reinterpret_cast<A
*>((C
*) 0)) bar
;
32 decltype(reinterpret_cast<C
*>((A
*) 0)) baz
;
35 void reinterpret_not_defined_class(B
*b
, C
*c
) {
36 // Should not fail if class has no definition.
37 (void)*reinterpret_cast<C
*>(b
);
38 (void)*reinterpret_cast<B
*>(c
);
40 (void)reinterpret_cast<C
&>(*b
);
41 (void)reinterpret_cast<B
&>(*c
);
44 // Do not fail on erroneous classes with fields of incompletely-defined types.
45 // Base class is malformed.
46 namespace BaseMalformed
{
47 struct A
; // expected-note {{forward declaration of 'BaseMalformed::A'}}
49 A a
; // expected-error {{field has incomplete type 'A'}}
51 struct C
: public B
{} c
;
52 B
*b
= reinterpret_cast<B
*>(&c
);
53 } // end anonymous namespace
55 // Child class is malformed.
56 namespace ChildMalformed
{
57 struct A
; // expected-note {{forward declaration of 'ChildMalformed::A'}}
60 A a
; // expected-error {{field has incomplete type 'A'}}
62 B
*b
= reinterpret_cast<B
*>(&c
);
63 } // end anonymous namespace
65 // Base class outside upcast base-chain is malformed.
66 namespace BaseBaseMalformed
{
67 struct A
; // expected-note {{forward declaration of 'BaseBaseMalformed::A'}}
69 struct X
{ A a
; }; // expected-error {{field has incomplete type 'A'}}
72 B
*p
= reinterpret_cast<B
*>(&c
);
75 namespace InheritanceMalformed
{
76 struct A
; // expected-note {{forward declaration of 'InheritanceMalformed::A'}}
77 struct B
: A
{}; // expected-error {{base class has incomplete type}}
79 B
*p
= reinterpret_cast<B
*>(&c
);
82 // Virtual base class outside upcast base-chain is malformed.
83 namespace VBaseMalformed
{
84 struct A
; // expected-note {{forward declaration of 'VBaseMalformed::A'}}
85 struct X
{ A a
; }; // expected-error {{field has incomplete type 'A'}}
86 struct B
: public virtual X
{};
88 B
*p
= reinterpret_cast<B
*>(&c
);
91 void reinterpret_not_updowncast(A
*pa
, const A
*pca
, A
&a
, const A
&ca
) {
92 (void)*reinterpret_cast<C
*>(pa
);
93 (void)*reinterpret_cast<const C
*>(pa
);
94 (void)*reinterpret_cast<volatile C
*>(pa
);
95 (void)*reinterpret_cast<const volatile C
*>(pa
);
97 (void)*reinterpret_cast<const C
*>(pca
);
98 (void)*reinterpret_cast<const volatile C
*>(pca
);
100 (void)reinterpret_cast<C
&>(a
);
101 (void)reinterpret_cast<const C
&>(a
);
102 (void)reinterpret_cast<volatile C
&>(a
);
103 (void)reinterpret_cast<const volatile C
&>(a
);
105 (void)reinterpret_cast<const C
&>(ca
);
106 (void)reinterpret_cast<const volatile C
&>(ca
);
109 void reinterpret_pointer_downcast(A
*a
, const A
*ca
) {
110 (void)*reinterpret_cast<DA
*>(a
);
111 (void)*reinterpret_cast<const DA
*>(a
);
112 (void)*reinterpret_cast<volatile DA
*>(a
);
113 (void)*reinterpret_cast<const volatile DA
*>(a
);
115 (void)*reinterpret_cast<const DA
*>(ca
);
116 (void)*reinterpret_cast<const volatile DA
*>(ca
);
118 (void)*reinterpret_cast<DDA
*>(a
);
119 (void)*reinterpret_cast<DAo
*>(a
);
120 (void)*reinterpret_cast<DAi
*>(a
);
121 // expected-warning@+2 {{'reinterpret_cast' to class 'DVA *' from its virtual base 'A *' behaves differently from 'static_cast'}}
122 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
123 (void)*reinterpret_cast<DVA
*>(a
);
124 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
126 // expected-warning@+2 {{'reinterpret_cast' to class 'DDVA *' from its virtual base 'A *' behaves differently from 'static_cast'}}
127 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
128 (void)*reinterpret_cast<DDVA
*>(a
);
129 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
131 // expected-warning@+2 {{'reinterpret_cast' to class 'DMA *' from its virtual base 'A *' behaves differently from 'static_cast'}}
132 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
133 (void)*reinterpret_cast<DMA
*>(a
);
134 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
137 void reinterpret_reference_downcast(A a
, A
&ra
, const A
&cra
) {
138 (void)reinterpret_cast<DA
&>(a
);
139 (void)reinterpret_cast<const DA
&>(a
);
140 (void)reinterpret_cast<volatile DA
&>(a
);
141 (void)reinterpret_cast<const volatile DA
&>(a
);
143 (void)reinterpret_cast<DA
&>(ra
);
144 (void)reinterpret_cast<const DA
&>(ra
);
145 (void)reinterpret_cast<volatile DA
&>(ra
);
146 (void)reinterpret_cast<const volatile DA
&>(ra
);
148 (void)reinterpret_cast<const DA
&>(cra
);
149 (void)reinterpret_cast<const volatile DA
&>(cra
);
151 (void)reinterpret_cast<DDA
&>(a
);
152 (void)reinterpret_cast<DAo
&>(a
);
153 (void)reinterpret_cast<DAi
&>(a
);
154 // expected-warning@+2 {{'reinterpret_cast' to class 'DVA &' from its virtual base 'A' behaves differently from 'static_cast'}}
155 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
156 (void)reinterpret_cast<DVA
&>(a
);
157 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
159 // expected-warning@+2 {{'reinterpret_cast' to class 'DDVA &' from its virtual base 'A' behaves differently from 'static_cast'}}
160 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
161 (void)reinterpret_cast<DDVA
&>(a
);
162 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
164 // expected-warning@+2 {{'reinterpret_cast' to class 'DMA &' from its virtual base 'A' behaves differently from 'static_cast'}}
165 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
166 (void)reinterpret_cast<DMA
&>(a
);
167 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
170 void reinterpret_pointer_upcast(DA
*da
, const DA
*cda
, DDA
*dda
, DAo
*dao
,
171 DAi
*dai
, DVA
*dva
, DDVA
*ddva
, DMA
*dma
) {
172 (void)*reinterpret_cast<A
*>(da
);
173 (void)*reinterpret_cast<const A
*>(da
);
174 (void)*reinterpret_cast<volatile A
*>(da
);
175 (void)*reinterpret_cast<const volatile A
*>(da
);
177 (void)*reinterpret_cast<const A
*>(cda
);
178 (void)*reinterpret_cast<const volatile A
*>(cda
);
180 (void)*reinterpret_cast<A
*>(dda
);
181 (void)*reinterpret_cast<DA
*>(dda
);
182 (void)*reinterpret_cast<A
*>(dao
);
183 (void)*reinterpret_cast<A
*>(dai
);
184 // expected-warning@+2 {{'reinterpret_cast' from class 'DVA *' to its virtual base 'A *' behaves differently from 'static_cast'}}
185 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
186 (void)*reinterpret_cast<A
*>(dva
);
187 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
189 // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA *' to its virtual base 'A *' behaves differently from 'static_cast'}}
190 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
191 (void)*reinterpret_cast<A
*>(ddva
);
192 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
194 // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA *' to its virtual base 'DA *' behaves differently from 'static_cast'}}
195 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
196 (void)*reinterpret_cast<DA
*>(ddva
);
197 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
199 // expected-warning@+2 {{'reinterpret_cast' from class 'DMA *' to its virtual base 'A *' behaves differently from 'static_cast'}}
200 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
201 (void)*reinterpret_cast<A
*>(dma
);
202 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
204 // expected-warning@+2 {{'reinterpret_cast' from class 'DMA *' to its virtual base 'DA *' behaves differently from 'static_cast'}}
205 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
206 (void)*reinterpret_cast<DA
*>(dma
);
207 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
210 void reinterpret_reference_upcast(DA
&da
, const DA
&cda
, DDA
&dda
, DAo
&dao
,
211 DAi
&dai
, DVA
&dva
, DDVA
&ddva
, DMA
&dma
) {
212 (void)reinterpret_cast<A
&>(da
);
213 (void)reinterpret_cast<const A
&>(da
);
214 (void)reinterpret_cast<volatile A
&>(da
);
215 (void)reinterpret_cast<const volatile A
&>(da
);
217 (void)reinterpret_cast<const A
&>(cda
);
218 (void)reinterpret_cast<const volatile A
&>(cda
);
220 (void)reinterpret_cast<A
&>(dda
);
221 (void)reinterpret_cast<DA
&>(dda
);
222 (void)reinterpret_cast<A
&>(dao
);
223 (void)reinterpret_cast<A
&>(dai
);
224 // expected-warning@+2 {{'reinterpret_cast' from class 'DVA' to its virtual base 'A &' behaves differently from 'static_cast'}}
225 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
226 (void)reinterpret_cast<A
&>(dva
);
227 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
229 // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA' to its virtual base 'A &' behaves differently from 'static_cast'}}
230 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
231 (void)reinterpret_cast<A
&>(ddva
);
232 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
234 // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA' to its virtual base 'DA &' behaves differently from 'static_cast'}}
235 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
236 (void)reinterpret_cast<DA
&>(ddva
);
237 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
239 // expected-warning@+2 {{'reinterpret_cast' from class 'DMA' to its virtual base 'A &' behaves differently from 'static_cast'}}
240 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
241 (void)reinterpret_cast<A
&>(dma
);
242 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
244 // expected-warning@+2 {{'reinterpret_cast' from class 'DMA' to its virtual base 'DA &' behaves differently from 'static_cast'}}
245 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
246 (void)reinterpret_cast<DA
&>(dma
);
247 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
255 virtual int foo() { return x
; }
261 class H
: public E
, public A
{
264 class I
: virtual public F
{
268 typedef volatile K L
;
270 void different_subobject_downcast(E
*e
, F
*f
, A
*a
) {
271 // expected-warning@+2 {{'reinterpret_cast' to class 'F *' from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
272 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
273 (void)reinterpret_cast<F
*>(e
);
274 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
276 // expected-warning@+2 {{'reinterpret_cast' to class 'G *' from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
277 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
278 (void)reinterpret_cast<G
*>(e
);
279 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
281 (void)reinterpret_cast<H
*>(e
);
282 // expected-warning@+2 {{'reinterpret_cast' to class 'I *' from its virtual base 'E *' behaves differently from 'static_cast'}}
283 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
284 (void)reinterpret_cast<I
*>(e
);
285 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
288 (void)reinterpret_cast<G
*>(f
);
289 // expected-warning@+2 {{'reinterpret_cast' to class 'I *' from its virtual base 'F *' behaves differently from 'static_cast'}}
290 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
291 (void)reinterpret_cast<I
*>(f
);
292 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
295 // In MS ABI mode, A is at non-zero offset in H.
296 // expected-warning@+3 {{'reinterpret_cast' to class 'H *' from its base at non-zero offset 'A *' behaves differently from 'static_cast'}}
297 // expected-note@+2 {{use 'static_cast'}}
299 (void)reinterpret_cast<H
*>(a
);
301 // expected-warning@+2 {{'reinterpret_cast' to class 'K' (aka 'const F *') from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
302 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
303 (void)reinterpret_cast<L
>(e
);
304 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
307 void different_subobject_upcast(F
*f
, G
*g
, H
*h
, I
*i
) {
308 // expected-warning@+2 {{'reinterpret_cast' from class 'F *' to its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
309 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
310 (void)reinterpret_cast<E
*>(f
);
311 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
313 (void)reinterpret_cast<F
*>(g
);
314 // expected-warning@+2 {{'reinterpret_cast' from class 'G *' to its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
315 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
316 (void)reinterpret_cast<E
*>(g
);
317 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
319 (void)reinterpret_cast<E
*>(h
);
322 // In MS ABI mode, A is at non-zero offset in H.
323 // expected-warning@+3 {{'reinterpret_cast' from class 'H *' to its base at non-zero offset 'A *' behaves differently from 'static_cast'}}
324 // expected-note@+2 {{use 'static_cast'}}
326 (void)reinterpret_cast<A
*>(h
);
328 // expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'F *' behaves differently from 'static_cast'}}
329 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
330 (void)reinterpret_cast<F
*>(i
);
331 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
333 // expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'E *' behaves differently from 'static_cast'}}
334 // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
335 (void)reinterpret_cast<E
*>(i
);
336 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"