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