diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C | |
download | cbb-gcc-4.6.4-upstream.tar.bz2 cbb-gcc-4.6.4-upstream.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/ptrmem.C')
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C | 146 |
1 files changed, 146 insertions, 0 deletions
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 000000000..077fa5084 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C @@ -0,0 +1,146 @@ +// { dg-do run } +// { dg-options "-fno-strict-aliasing" } +// Origin: Mark Mitchell <mark@codesourcery.com> + +/* Generally, the lowest bit of the ptr is used to indicate whether a + ptr-to-mem-func points to a virtual or a non-virtual member + function. However, some platforms use all bits to encode a + function pointer. Such platforms use the lowest bit of the delta, + that is shifted left by one bit. */ +#if defined __MN10300__ || defined __SH5__ || defined __arm__ || defined __thumb__ || defined __mips__ +#define ADJUST_PTRFN(func, virt) ((void (*)())(func)) +#define ADJUST_DELTA(delta, virt) (((delta) << 1) + !!(virt)) +#else +#define ADJUST_PTRFN(func, virt) ((void (*)())((ptrdiff_t)(func) + !!(virt))) +#define ADJUST_DELTA(delta, virt) (delta) +#endif + +/* IA64 uses function descriptors instead of function pointers in its + vtables, which means that we can't meaningfully compare them directly. */ +#if defined __ia64__ +#define CMP_PTRFN(A, B) (*(void **)(A) == *(void **)(B)) +#define VPTE_SIZE (16) +#else +#define CMP_PTRFN(A, B) ((A) == (B)) +#define VPTE_SIZE sizeof(void *) +#endif + +#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 + +// Check that pointers-to-member functions are represented correctly. + +#include <cstddef> + +struct S +{ + int i; + int j; +}; + +// Because S does not have a VPTR, it will not be a primary base of T, +// and will therefore end up at a nonzero 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 _ZN1T1fEv (); +extern "C" void _ZN1T1gEv (); +extern "C" void _ZN1T1hEv (); + +// This structure is a C representation of a pointer-to-member. + +struct ptrmemfunc +{ + void (*ptr) (); + ptrdiff_t adj; +}; + +typedef int S::*sdp; +typedef void (S::*sp)(); +typedef void (T::*tp)(); + +int +main () +{ + S s; + T t; + sp x; + tp y; + ptrmemfunc *xp = (ptrmemfunc *) &x; + ptrmemfunc *yp = (ptrmemfunc *) &y; + ptrdiff_t delta = ((char *) &t) - ((char*) (S*) (&t)); + + // Pointers-to-function-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 (! CMP_PTRFN (yp->ptr, ADJUST_PTRFN (&_ZN1T1fEv, 0))) + return 5; + if (yp->adj != ADJUST_DELTA (0, 0)) + return 6; + x = (sp) y; + if (! CMP_PTRFN (xp->ptr, ADJUST_PTRFN (&_ZN1T1fEv, 0))) + return 7; + if (xp->adj != ADJUST_DELTA (delta, 0)) + return 8; + + // For a virtual function, we should see the vtable offset, plus + // one. `T::h' is in the second slot: the vtable pointer points to + // the first virtual function. + y = &T::h; + if (yp->ptr != ADJUST_PTRFN (VPTE_SIZE, 1)) + return 9; + if (yp->adj != ADJUST_DELTA (0, 1)) + return 10; + x = (sp) y; + if (xp->ptr != ADJUST_PTRFN (VPTE_SIZE, 1)) + return 11; + if (xp->adj != ADJUST_DELTA (delta, 1)) + return 12; + + // Pointers-to-data-members should have the same size and alignment + // as a ptrdiff_t. + if (sizeof (sdp) != sizeof (ptrdiff_t)) + return 13; + if (__alignof__ (sdp) != __alignof__ (ptrdiff_t)) + return 14; + + // The value of a pointer-to-data member should be the offset from + // the start of the structure. + sdp z = &S::j; + if ((char *) &s.j - (char *) &s != *((ptrdiff_t *) &z)) + return 15; + z = 0; + if (*((ptrdiff_t *) &z) != -1) + return 16; +} + +#else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */ + +int main () +{ +} + +#endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */ |