blob: 67902f7a90d80326173f6fc662dc4b82a810c6d3 [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
Jordan Rose5fd1fac2013-03-28 19:09:40 +00002// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fdiagnostics-parseable-fixits -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s 2>&1 | FileCheck %s
John McCall437da052013-03-22 02:58:14 +00003
4// PR 13824
5class A {
6};
7class DA : public A {
8};
9class DDA : public DA {
10};
11class DAo : protected A {
12};
13class DAi : private A {
14};
15
16class DVA : public virtual A {
17};
18class DDVA : public virtual DA {
19};
20class DMA : public virtual A, public virtual DA {
21};
22
23class B;
24
25struct 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
32void 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
John McCallfdb468f2013-03-27 00:03:48 +000041// Do not fail on erroneous classes with fields of incompletely-defined types.
42// Base class is malformed.
43namespace 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.
53namespace 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.
63namespace 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
72namespace 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.
80namespace 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
John McCall437da052013-03-22 02:58:14 +000088void 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
106void 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000121 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
122
John McCall437da052013-03-22 02:58:14 +0000123 // 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000126 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
127
John McCall437da052013-03-22 02:58:14 +0000128 // 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000131 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
John McCall437da052013-03-22 02:58:14 +0000132}
133
134void 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000154 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
155
John McCall437da052013-03-22 02:58:14 +0000156 // 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000159 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
160
John McCall437da052013-03-22 02:58:14 +0000161 // 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000164 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
John McCall437da052013-03-22 02:58:14 +0000165}
166
167void 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000184 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
185
John McCall437da052013-03-22 02:58:14 +0000186 // 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000189 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
190
John McCall437da052013-03-22 02:58:14 +0000191 // 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000194 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
195
John McCall437da052013-03-22 02:58:14 +0000196 // 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000199 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
200
John McCall437da052013-03-22 02:58:14 +0000201 // 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000204 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
John McCall437da052013-03-22 02:58:14 +0000205}
206
207void 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000224 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
225
John McCall437da052013-03-22 02:58:14 +0000226 // 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000229 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
230
John McCall437da052013-03-22 02:58:14 +0000231 // 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000234 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
235
John McCall437da052013-03-22 02:58:14 +0000236 // 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000239 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
240
John McCall437da052013-03-22 02:58:14 +0000241 // 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000244 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
John McCall437da052013-03-22 02:58:14 +0000245}
246
247struct E {
248 int x;
249};
250
251class F : public E {
252 virtual int foo() { return x; }
253};
254
255class G : public F {
256};
257
258class H : public E, public A {
259};
260
261class I : virtual public F {
262};
263
264typedef const F * K;
265typedef volatile K L;
266
267void 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000271 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
272
John McCall437da052013-03-22 02:58:14 +0000273 // 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000276 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
277
John McCall437da052013-03-22 02:58:14 +0000278 (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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000282 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
283
John McCall437da052013-03-22 02:58:14 +0000284
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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000289 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
John McCall437da052013-03-22 02:58:14 +0000290
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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000296 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
John McCall437da052013-03-22 02:58:14 +0000297}
298
299void 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000303 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
John McCall437da052013-03-22 02:58:14 +0000304
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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000309 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
John McCall437da052013-03-22 02:58:14 +0000310
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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000317 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
318
John McCall437da052013-03-22 02:58:14 +0000319 // 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);
Jordan Rose5fd1fac2013-03-28 19:09:40 +0000322 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
John McCall437da052013-03-22 02:58:14 +0000323}