Home | History | Annotate | Download | only in SemaCXX
      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 { //expected-warning{{direct base 'A' is inaccessible due to ambiguity:\n    class DMA -> class A\n    class DMA -> class DA -> class A}}
     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