aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2000-02-22 22:17:33 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2000-02-22 22:17:33 +0000
commitfa2e34e8f267ce9944c3ce053b5785368ecbd89f (patch)
tree11ffb949bd5abe52fc8b7cae5d75b8f8f9c9fcb5
parentcfbad224f649250458ea53381c8bcb9064b21d13 (diff)
downloadgcc-fa2e34e8f267ce9944c3ce053b5785368ecbd89f.zip
gcc-fa2e34e8f267ce9944c3ce053b5785368ecbd89f.tar.gz
gcc-fa2e34e8f267ce9944c3ce053b5785368ecbd89f.tar.bz2
* g++.old-deja/g++.abi/ptrmem.C: New test.
From-SVN: r32107
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C103
2 files changed, 107 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 77a1ba6..d5dd427 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2000-02-22 Mark Mitchell <mark@codesourcery.com>
+
+ * g++.old-deja/g++.abi/ptrmem.C: New test.
+
2000-02-19 Richard Henderson <rth@cygnus.com>
* gcc.c-torture/compile/init-3.c: New.
diff --git a/gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C b/gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C
new file mode 100644
index 0000000..8bf53fd
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C
@@ -0,0 +1,103 @@
+// Special g++ Options: -fno-strict-aliasing
+// Origin: Mark Mitchell <mark@codesourcery.com>
+
+#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
+
+// Check that pointers-to-member functions are represented correctly.
+
+#include <cstddef>
+
+struct S
+{
+ int i;
+};
+
+// Because S does not have a VPTR, it will not be a primary base of T,
+// and will therefore end up at a non-zero offset.
+
+struct T : public S
+{
+ void f () {}
+ virtual void g () {}
+ virtual void h () {}
+};
+
+// Provide access to the raw function pointers. This is
+// mangling-dependent.
+
+extern "C" void f__1T ();
+extern "C" void g__1T ();
+extern "C" void h__1T ();
+
+// This structure is a C representation of a pointer-to-member.
+
+struct ptrmemfunc
+{
+ void (*ptr) ();
+ ptrdiff_t adj;
+};
+
+typedef void (S::*sp)();
+typedef void (T::*tp)();
+
+int
+main ()
+{
+ T t;
+ sp x;
+ tp y;
+ ptrmemfunc *xp = (ptrmemfunc *) &x;
+ ptrmemfunc *yp = (ptrmemfunc *) &y;
+ ptrdiff_t delta = ((char *) &t) - ((char*) (S*) (&t));
+
+ // Pointers-to-members should have the same size and alignment as
+ // the PTRMEMFUNC type.
+ if (sizeof (sp) != sizeof (ptrmemfunc))
+ return 1;
+ if (__alignof__ (sp) != __alignof__ (ptrmemfunc))
+ return 2;
+
+ // The NULL pointer-to-member should have a NULL first PTR field.
+ x = 0;
+ if (xp->ptr != 0)
+ return 3;
+ y = x;
+ if (yp->ptr != 0)
+ return 4;
+
+ // A non-virtual function should have a pointer to the function.
+ // There should be no adjustment for the `T' version, and an
+ // appropriate adjustment for the `S' version.
+ y = &T::f;
+ if (yp->ptr != &f__1T)
+ return 5;
+ if (yp->adj != 0)
+ return 6;
+ x = (sp) y;
+ if (xp->ptr != &f__1T)
+ return 7;
+ if (xp->adj != delta)
+ return 8;
+
+ // For a virtual function, we should see twice the vtable index,
+ // plus one. `T::h' is in the third slot: there's the RTTI entry,
+ // then the two virtual functions.
+ y = &T::h;
+ if ((ptrdiff_t) yp->ptr != 7)
+ return 9;
+ if (yp->adj != 0)
+ return 10;
+ x = (sp) y;
+ if ((ptrdiff_t) xp->ptr != 7)
+ return 11;
+ if (xp->adj != delta)
+ return 12;
+}
+
+#else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
+
+int main ()
+{
+}
+
+#endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */