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 3 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 6 7 // PR 13824 8 class A { 9 }; 10 class DA : public A { 11 }; 12 class DDA : public DA { 13 }; 14 class DAo : protected A { 15 }; 16 class DAi : private A { 17 }; 18 19 class DVA : public virtual A { 20 }; 21 class DDVA : public virtual DA { 22 }; 23 class DMA : public virtual A, public virtual DA { 24 }; 25 26 class B; 27 28 struct C { 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; 33 }; 34 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); 39 40 (void)reinterpret_cast<C &>(*b); 41 (void)reinterpret_cast<B &>(*c); 42 } 43 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'}} 48 struct B { 49 A a; // expected-error {{field has incomplete type 'BaseMalformed::A'}} 50 }; 51 struct C : public B {} c; 52 B *b = reinterpret_cast<B *>(&c); 53 } // end anonymous namespace 54 55 // Child class is malformed. 56 namespace ChildMalformed { 57 struct A; // expected-note {{forward declaration of 'ChildMalformed::A'}} 58 struct B {}; 59 struct C : public B { 60 A a; // expected-error {{field has incomplete type 'ChildMalformed::A'}} 61 } c; 62 B *b = reinterpret_cast<B *>(&c); 63 } // end anonymous namespace 64 65 // Base class outside upcast base-chain is malformed. 66 namespace BaseBaseMalformed { 67 struct A; // expected-note {{forward declaration of 'BaseBaseMalformed::A'}} 68 struct Y {}; 69 struct X { A a; }; // expected-error {{field has incomplete type 'BaseBaseMalformed::A'}} 70 struct B : Y, X {}; 71 struct C : B {} c; 72 B *p = reinterpret_cast<B*>(&c); 73 } 74 75 namespace InheritanceMalformed { 76 struct A; // expected-note {{forward declaration of 'InheritanceMalformed::A'}} 77 struct B : A {}; // expected-error {{base class has incomplete type}} 78 struct C : B {} c; 79 B *p = reinterpret_cast<B*>(&c); 80 } 81 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 'VBaseMalformed::A'}} 86 struct B : public virtual X {}; 87 struct C : B {} c; 88 B *p = reinterpret_cast<B*>(&c); 89 } 90 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); 96 97 (void)*reinterpret_cast<const C *>(pca); 98 (void)*reinterpret_cast<const volatile C *>(pca); 99 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); 104 105 (void)reinterpret_cast<const C &>(ca); 106 (void)reinterpret_cast<const volatile C &>(ca); 107 } 108 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); 114 115 (void)*reinterpret_cast<const DA *>(ca); 116 (void)*reinterpret_cast<const volatile DA *>(ca); 117 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" 125 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" 130 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" 135 } 136 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); 142 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); 147 148 (void)reinterpret_cast<const DA &>(cra); 149 (void)reinterpret_cast<const volatile DA &>(cra); 150 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" 158 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" 163 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" 168 } 169 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); 176 177 (void)*reinterpret_cast<const A *>(cda); 178 (void)*reinterpret_cast<const volatile A *>(cda); 179 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" 188 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" 193 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" 198 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" 203 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" 208 } 209 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); 216 217 (void)reinterpret_cast<const A &>(cda); 218 (void)reinterpret_cast<const volatile A &>(cda); 219 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" 228 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" 233 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" 238 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" 243 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" 248 } 249 250 struct E { 251 int x; 252 }; 253 254 class F : public E { 255 virtual int foo() { return x; } 256 }; 257 258 class G : public F { 259 }; 260 261 class H : public E, public A { 262 }; 263 264 class I : virtual public F { 265 }; 266 267 typedef const F * K; 268 typedef volatile K L; 269 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" 275 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" 280 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" 286 287 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" 293 294 #ifdef MSABI 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'}} 298 #endif 299 (void)reinterpret_cast<H *>(a); 300 301 // 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'}} 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" 305 } 306 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" 312 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" 318 319 (void)reinterpret_cast<E *>(h); 320 321 #ifdef MSABI 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'}} 325 #endif 326 (void)reinterpret_cast<A *>(h); 327 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" 332 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" 337 } 338