summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/g++.old-deja/g++.abi/vtable2.C
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
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.
Diffstat (limited to 'gcc/testsuite/g++.old-deja/g++.abi/vtable2.C')
-rw-r--r--gcc/testsuite/g++.old-deja/g++.abi/vtable2.C213
1 files changed, 213 insertions, 0 deletions
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 <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) */