Home | History | Annotate | Download | only in jni
      1 // { dg-do run  }
      2 // { dg-options "-fno-strict-aliasing" }
      3 // Origin: Mark Mitchell <mark (at) codesourcery.com>
      4 
      5 #if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
      6 
      7 #include <stddef.h>
      8 
      9 struct S0
     10 {
     11   virtual void s0 ();
     12 };
     13 
     14 struct S1 : virtual public S0
     15 {
     16   virtual void s1 ();
     17 };
     18 
     19 struct S2 : virtual public S1
     20 {
     21   virtual void s1 ();
     22   virtual void s0 ();
     23 };
     24 
     25 struct S3
     26 {
     27   virtual void s3 ();
     28 };
     29 
     30 struct S4 : public S3, virtual public S2
     31 {
     32   virtual void s1 ();
     33 };
     34 
     35 void S0::s0 ()
     36 {
     37 }
     38 
     39 void S1::s1 ()
     40 {
     41 }
     42 
     43 void S2::s1 ()
     44 {
     45 }
     46 
     47 void S2::s0 ()
     48 {
     49 }
     50 
     51 void S3::s3 ()
     52 {
     53 }
     54 
     55 void S4::s1 ()
     56 {
     57 }
     58 
     59 /* The vtables should look like:
     60 
     61    S0 primary vtable
     62 
     63      S0 offset to top
     64      S0 RTTI
     65      S0::s0
     66 
     67    =================
     68 
     69    S1 primary vtable
     70 
     71      S0::s0 vcall offset
     72      S0 vbase offset
     73      S1 offset to top
     74      S1 RTTI
     75      S0::s0
     76      S1::s1
     77 
     78    =================
     79 
     80    S2 primary vtable
     81 
     82      S2::s1 vcall offset
     83      S1 vbase offset
     84      S2::s0 vcall offset
     85      S0 vbase offset
     86      S2 offset to top
     87      S2 RTTI
     88      S2::s0
     89      S2::s1
     90 
     91    =================
     92 
     93    S3 primary vtable
     94 
     95      S3 offset to top
     96      S3 RTTI
     97      S3::s3
     98 
     99    =================
    100 
    101    S4 primary vtable
    102 
    103      vbase offset for S0
    104      vbase offset for S1
    105      vbase offset for S2
    106      S4 offset to top
    107      S4 RTTI
    108      S3::s3
    109      S4::s1
    110 
    111    S2-in-S4 secondary vtable
    112 
    113      S1 vbase offset
    114      S4::s1 vcall offset
    115      S0 vbase offset
    116      S2:s0 vcall offset
    117      S2 offset to top
    118      S4 RTTI
    119      S2::s0
    120      S4::s1
    121 
    122 */
    123 
    124 // These are tricks to allow us to get raw function pointers for
    125 // member functions.
    126 extern "C" {
    127   /* We can use weakref here without dg-require-weak, because we know
    128      the symbols are defined, so we don't actually issue the .weak
    129      directives.  */
    130   static void S3_s3 () __attribute__((__weakref__ ("_ZN2S32s3Ev")));
    131   static void S4_s1 () __attribute__((__weakref__ ("_ZN2S42s1Ev")));
    132 }
    133 
    134 // IA-64 uses function descriptors not function pointers in its vtables.
    135 #if defined __ia64__
    136 #define CMP_VPTR(A, B)	(*(void **)(A) == *(void **)(B))
    137 #ifdef _LP64
    138 #define INC_VPTR(A)	((A) += 2)
    139 #define INC_VDATA(A,N)	((A) += (N))
    140 #else
    141 #define INC_VPTR(A)	((A) += 4)
    142 #define INC_VDATA(A,N)	((A) += 2*(N))
    143 #endif
    144 #else
    145 #define CMP_VPTR(A, B)	(*(A) == (ptrdiff_t)(B))
    146 #define INC_VPTR(A)	((A) += 1)
    147 #define INC_VDATA(A,N)	((A) += (N))
    148 #endif
    149 
    150 int main ()
    151 {
    152   S4 s4;
    153   ptrdiff_t **vptr;
    154   ptrdiff_t *vtbl;
    155 
    156   // Set vtbl to point at the beginning of S4's primary vtable.
    157   vptr = (ptrdiff_t **) &s4;
    158   vtbl = *vptr;
    159   INC_VDATA (vtbl, -5);
    160 
    161   if (*vtbl != ((char*) (S0*) &s4) - (char*) &s4)
    162     return 1;
    163   INC_VDATA (vtbl, 1);
    164   if (*vtbl != ((char*) (S1*) &s4) - (char*) &s4)
    165     return 2;
    166   INC_VDATA (vtbl, 1);
    167   if (*vtbl != ((char*) (S2*) &s4) - (char*) &s4)
    168     return 3;
    169   INC_VDATA (vtbl, 1);
    170   if (*vtbl != 0)
    171     return 4;
    172   INC_VDATA (vtbl, 1);
    173   // Skip the RTTI entry.
    174   INC_VDATA (vtbl, 1);
    175   if (! CMP_VPTR (vtbl, &S3_s3))
    176     return 5;
    177   INC_VPTR (vtbl);
    178   if (! CMP_VPTR (vtbl, &S4_s1))
    179     return 6;
    180   INC_VPTR (vtbl);
    181   // The S1 vbase offset.
    182   if (*vtbl != 0)
    183     return 7;
    184   INC_VDATA (vtbl, 1);
    185   // The S4::s1 vcall offset is negative; once you convert to S2, you
    186   // have to convert to S4 to find the final overrider.
    187   if (*vtbl != ((char*) &s4 - (char*) (S2*) &s4))
    188     return 8;
    189   INC_VDATA (vtbl, 1);
    190   if (*vtbl != 0)
    191     return 9;
    192   INC_VDATA (vtbl, 1);
    193   if (*vtbl != 0)
    194     return 10;
    195   INC_VDATA (vtbl, 1);
    196   // Now we're at the S2 offset to top entry.
    197   if (*vtbl != ((char*) &s4 - (char*) (S2*) &s4))
    198     return 11;
    199   INC_VDATA (vtbl, 1);
    200   // Skip the RTTI entry.
    201   INC_VDATA (vtbl, 1);
    202   // Skip the reint maining virtual functions -- they are thunks.
    203   INC_VPTR (vtbl);
    204   INC_VPTR (vtbl);
    205 }
    206 
    207 #else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
    208 
    209 int main ()
    210 {
    211 }
    212 
    213 #endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
    214