* g++.old-deja/g++.abi/ptrmem.C: New test.
authorMark Mitchell <mark@codesourcery.com>
Tue, 22 Feb 2000 22:17:33 +0000 (22:17 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 22 Feb 2000 22:17:33 +0000 (22:17 +0000)
From-SVN: r32107

gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C [new file with mode: 0644]

index 77a1ba61501652cfb8645f78bf0ec99116ca5b22..d5dd4272eb2f4e697d88f72f6fb2f49c6be2d677 100644 (file)
@@ -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 (file)
index 0000000..8bf53fd
--- /dev/null
@@ -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) */