214 lines
3.8 KiB
C
214 lines
3.8 KiB
C
// { dg-do run }
|
|
// { dg-options "-fno-strict-aliasing" }
|
|
// Origin: Mark Mitchell <mark@codesourcery.com>
|
|
|
|
#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
|
|
|
|
#include <stddef.h>
|
|
|
|
struct S0
|
|
{
|
|
virtual void s0 ();
|
|
};
|
|
|
|
struct S1 : virtual public S0
|
|
{
|
|
virtual void s1 ();
|
|
};
|
|
|
|
struct S2 : virtual public S1
|
|
{
|
|
virtual void s1 ();
|
|
virtual void s0 ();
|
|
};
|
|
|
|
struct S3
|
|
{
|
|
virtual void s3 ();
|
|
};
|
|
|
|
struct S4 : public S3, virtual public S2
|
|
{
|
|
virtual void s1 ();
|
|
};
|
|
|
|
void S0::s0 ()
|
|
{
|
|
}
|
|
|
|
void S1::s1 ()
|
|
{
|
|
}
|
|
|
|
void S2::s1 ()
|
|
{
|
|
}
|
|
|
|
void S2::s0 ()
|
|
{
|
|
}
|
|
|
|
void S3::s3 ()
|
|
{
|
|
}
|
|
|
|
void S4::s1 ()
|
|
{
|
|
}
|
|
|
|
/* The vtables should look like:
|
|
|
|
S0 primary vtable
|
|
|
|
S0 offset to top
|
|
S0 RTTI
|
|
S0::s0
|
|
|
|
=================
|
|
|
|
S1 primary vtable
|
|
|
|
S0::s0 vcall offset
|
|
S0 vbase offset
|
|
S1 offset to top
|
|
S1 RTTI
|
|
S0::s0
|
|
S1::s1
|
|
|
|
=================
|
|
|
|
S2 primary vtable
|
|
|
|
S2::s1 vcall offset
|
|
S1 vbase offset
|
|
S2::s0 vcall offset
|
|
S0 vbase offset
|
|
S2 offset to top
|
|
S2 RTTI
|
|
S2::s0
|
|
S2::s1
|
|
|
|
=================
|
|
|
|
S3 primary vtable
|
|
|
|
S3 offset to top
|
|
S3 RTTI
|
|
S3::s3
|
|
|
|
=================
|
|
|
|
S4 primary vtable
|
|
|
|
vbase offset for S0
|
|
vbase offset for S1
|
|
vbase offset for S2
|
|
S4 offset to top
|
|
S4 RTTI
|
|
S3::s3
|
|
S4::s1
|
|
|
|
S2-in-S4 secondary vtable
|
|
|
|
S1 vbase offset
|
|
S4::s1 vcall offset
|
|
S0 vbase offset
|
|
S2:s0 vcall offset
|
|
S2 offset to top
|
|
S4 RTTI
|
|
S2::s0
|
|
S4::s1
|
|
|
|
*/
|
|
|
|
// These are tricks to allow us to get raw function pointers for
|
|
// member functions.
|
|
extern "C" {
|
|
/* We can use weakref here without dg-require-weak, because we know
|
|
the symbols are defined, so we don't actually issue the .weak
|
|
directives. */
|
|
static void S3_s3 () __attribute__((__weakref__ ("_ZN2S32s3Ev")));
|
|
static void S4_s1 () __attribute__((__weakref__ ("_ZN2S42s1Ev")));
|
|
}
|
|
|
|
// IA-64 uses function descriptors not function pointers in its vtables.
|
|
#if defined __ia64__
|
|
#define CMP_VPTR(A, B) (*(void **)(A) == *(void **)(B))
|
|
#ifdef _LP64
|
|
#define INC_VPTR(A) ((A) += 2)
|
|
#define INC_VDATA(A,N) ((A) += (N))
|
|
#else
|
|
#define INC_VPTR(A) ((A) += 4)
|
|
#define INC_VDATA(A,N) ((A) += 2*(N))
|
|
#endif
|
|
#else
|
|
#define CMP_VPTR(A, B) (*(A) == (ptrdiff_t)(B))
|
|
#define INC_VPTR(A) ((A) += 1)
|
|
#define INC_VDATA(A,N) ((A) += (N))
|
|
#endif
|
|
|
|
int main ()
|
|
{
|
|
S4 s4;
|
|
ptrdiff_t **vptr;
|
|
ptrdiff_t *vtbl;
|
|
|
|
// Set vtbl to point at the beginning of S4's primary vtable.
|
|
vptr = (ptrdiff_t **) &s4;
|
|
vtbl = *vptr;
|
|
INC_VDATA (vtbl, -5);
|
|
|
|
if (*vtbl != ((char*) (S0*) &s4) - (char*) &s4)
|
|
return 1;
|
|
INC_VDATA (vtbl, 1);
|
|
if (*vtbl != ((char*) (S1*) &s4) - (char*) &s4)
|
|
return 2;
|
|
INC_VDATA (vtbl, 1);
|
|
if (*vtbl != ((char*) (S2*) &s4) - (char*) &s4)
|
|
return 3;
|
|
INC_VDATA (vtbl, 1);
|
|
if (*vtbl != 0)
|
|
return 4;
|
|
INC_VDATA (vtbl, 1);
|
|
// Skip the RTTI entry.
|
|
INC_VDATA (vtbl, 1);
|
|
if (! CMP_VPTR (vtbl, &S3_s3))
|
|
return 5;
|
|
INC_VPTR (vtbl);
|
|
if (! CMP_VPTR (vtbl, &S4_s1))
|
|
return 6;
|
|
INC_VPTR (vtbl);
|
|
// The S1 vbase offset.
|
|
if (*vtbl != 0)
|
|
return 7;
|
|
INC_VDATA (vtbl, 1);
|
|
// The S4::s1 vcall offset is negative; once you convert to S2, you
|
|
// have to convert to S4 to find the final overrider.
|
|
if (*vtbl != ((char*) &s4 - (char*) (S2*) &s4))
|
|
return 8;
|
|
INC_VDATA (vtbl, 1);
|
|
if (*vtbl != 0)
|
|
return 9;
|
|
INC_VDATA (vtbl, 1);
|
|
if (*vtbl != 0)
|
|
return 10;
|
|
INC_VDATA (vtbl, 1);
|
|
// Now we're at the S2 offset to top entry.
|
|
if (*vtbl != ((char*) &s4 - (char*) (S2*) &s4))
|
|
return 11;
|
|
INC_VDATA (vtbl, 1);
|
|
// Skip the RTTI entry.
|
|
INC_VDATA (vtbl, 1);
|
|
// Skip the remaining virtual functions -- they are thunks.
|
|
INC_VPTR (vtbl);
|
|
INC_VPTR (vtbl);
|
|
}
|
|
|
|
#else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
|
|
|
|
int main ()
|
|
{
|
|
}
|
|
|
|
#endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
|