From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- gcc/testsuite/g++.old-deja/g++.abi/vtable2.C | 213 +++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 gcc/testsuite/g++.old-deja/g++.abi/vtable2.C (limited to 'gcc/testsuite/g++.old-deja/g++.abi/vtable2.C') diff --git a/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C b/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C new file mode 100644 index 000000000..b64f0fc25 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C @@ -0,0 +1,213 @@ +// { dg-do run } +// { dg-options "-fno-strict-aliasing" } +// Origin: Mark Mitchell + +#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 + +#include + +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) */ -- cgit v1.2.3