From e8c89d29703051af683fe65dc055089b61acde2f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 19 Dec 2003 15:00:53 +0100 Subject: unwind-ia64.c (ia64_copy_rbs): New function. * config/ia64/unwind-ia64.c (ia64_copy_rbs): New function. (unw_access_gr): Only call ia64_rse_rnat_addr if addr is above regstk_top. (uw_frame_state_for): Handle locations inside bundles. (uw_init_context_1): Initialize context->rnat. Set context->regstk_top to lowest rbs address which has nat collection in context->rnat. (uw_install_context): Fix rnat restoring. Restore ar.rsc to previous state. * config/ia64/linux.h (MD_FALLBACK_FRAME_STATE_FOR, MD_HANDLE_UNWABI): Handle unwinding through SA_ONSTACK frames. * gcc.dg/cleanup-10.c: New test. * gcc.dg/cleanup-11.c: New test. From-SVN: r74835 --- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/cleanup-10.c | 114 ++++++++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/cleanup-11.c | 114 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 233 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/cleanup-10.c create mode 100644 gcc/testsuite/gcc.dg/cleanup-11.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3010412f..33e006e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2003-12-19 Jakub Jelinek + * gcc.dg/cleanup-10.c: New test. + * gcc.dg/cleanup-11.c: New test. + +2003-12-19 Jakub Jelinek + PR c++/13239 * g++.dg/opt/expect1.C: New test. diff --git a/gcc/testsuite/gcc.dg/cleanup-10.c b/gcc/testsuite/gcc.dg/cleanup-10.c new file mode 100644 index 0000000..39923fd --- /dev/null +++ b/gcc/testsuite/gcc.dg/cleanup-10.c @@ -0,0 +1,114 @@ +/* { dg-do run { target i?86-*-linux* x86_64-*-linux* ia64-*-linux* alpha*-*-linux* powerpc*-*-linux* s390*-*-linux* sparc*-*-linux* mips*-*-linux* } } */ +/* { dg-options "-fasynchronous-unwind-tables -fexceptions -O2" } */ +/* Verify that cleanups work with exception handling through signal frames + on alternate stack. */ + +#include +#include +#include +#include + +static _Unwind_Reason_Code +force_unwind_stop (int version, _Unwind_Action actions, + _Unwind_Exception_Class exc_class, + struct _Unwind_Exception *exc_obj, + struct _Unwind_Context *context, + void *stop_parameter) +{ + if (actions & _UA_END_OF_STACK) + abort (); + return _URC_NO_REASON; +} + +static void force_unwind () +{ + struct _Unwind_Exception *exc = malloc (sizeof (*exc)); + exc->exception_class = 0; + exc->exception_cleanup = 0; + +#ifndef __USING_SJLJ_EXCEPTIONS__ + _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); +#else + _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0); +#endif + + abort (); +} + +int count; +char *null; + +static void counter (void *p __attribute__((unused))) +{ + ++count; +} + +static void handler (void *p __attribute__((unused))) +{ + if (count != 2) + abort (); + exit (0); +} + +static int __attribute__((noinline)) fn5 () +{ + char dummy __attribute__((cleanup (counter))); + force_unwind (); + return 0; +} + +static void fn4 (int sig, siginfo_t *info, void *ctx) +{ + char dummy __attribute__((cleanup (counter))); + fn5 (); + null = NULL; +} + +static void fn3 () +{ + abort (); +} + +static int __attribute__((noinline)) fn2 () +{ + *null = 0; + fn3 (); + return 0; +} + +static int __attribute__((noinline)) fn1 () +{ + stack_t ss; + struct sigaction s; + + ss.ss_size = 4 * sysconf (_SC_PAGESIZE); + if (ss.ss_size < SIGSTKSZ) + ss.ss_size = SIGSTKSZ; + ss.ss_sp = malloc (ss.ss_size); + if (ss.ss_sp == NULL) + exit (1); + ss.ss_flags = 0; + if (sigaltstack (&ss, NULL) < 0) + exit (1); + + sigemptyset (&s.sa_mask); + s.sa_sigaction = fn4; + s.sa_flags = SA_ONESHOT | SA_ONSTACK; + sigaction (SIGSEGV, &s, NULL); + fn2 (); + return 0; +} + +static int __attribute__((noinline)) fn0 () +{ + char dummy __attribute__((cleanup (handler))); + fn1 (); + null = 0; + return 0; +} + +int main() +{ + fn0 (); + abort (); +} diff --git a/gcc/testsuite/gcc.dg/cleanup-11.c b/gcc/testsuite/gcc.dg/cleanup-11.c new file mode 100644 index 0000000..9c47f6c --- /dev/null +++ b/gcc/testsuite/gcc.dg/cleanup-11.c @@ -0,0 +1,114 @@ +/* { dg-do run { target i?86-*-linux* x86_64-*-linux* ia64-*-linux* alpha*-*-linux* powerpc*-*-linux* s390*-*-linux* sparc*-*-linux* mips*-*-linux* } } */ +/* { dg-options "-fasynchronous-unwind-tables -fexceptions -O2" } */ +/* Verify that cleanups work with exception handling through realtime signal + frames on alternate stack. */ + +#include +#include +#include +#include + +static _Unwind_Reason_Code +force_unwind_stop (int version, _Unwind_Action actions, + _Unwind_Exception_Class exc_class, + struct _Unwind_Exception *exc_obj, + struct _Unwind_Context *context, + void *stop_parameter) +{ + if (actions & _UA_END_OF_STACK) + abort (); + return _URC_NO_REASON; +} + +static void force_unwind () +{ + struct _Unwind_Exception *exc = malloc (sizeof (*exc)); + exc->exception_class = 0; + exc->exception_cleanup = 0; + +#ifndef __USING_SJLJ_EXCEPTIONS__ + _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); +#else + _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0); +#endif + + abort (); +} + +int count; +char *null; + +static void counter (void *p __attribute__((unused))) +{ + ++count; +} + +static void handler (void *p __attribute__((unused))) +{ + if (count != 2) + abort (); + exit (0); +} + +static int __attribute__((noinline)) fn5 () +{ + char dummy __attribute__((cleanup (counter))); + force_unwind (); + return 0; +} + +static void fn4 (int sig, siginfo_t *info, void *ctx) +{ + char dummy __attribute__((cleanup (counter))); + fn5 (); + null = NULL; +} + +static void fn3 () +{ + abort (); +} + +static int __attribute__((noinline)) fn2 () +{ + *null = 0; + fn3 (); + return 0; +} + +static int __attribute__((noinline)) fn1 () +{ + stack_t ss; + struct sigaction s; + + ss.ss_size = 4 * sysconf (_SC_PAGESIZE); + if (ss.ss_size < SIGSTKSZ) + ss.ss_size = SIGSTKSZ; + ss.ss_sp = malloc (ss.ss_size); + if (ss.ss_sp == NULL) + exit (1); + ss.ss_flags = 0; + if (sigaltstack (&ss, NULL) < 0) + exit (1); + + sigemptyset (&s.sa_mask); + s.sa_sigaction = fn4; + s.sa_flags = SA_ONESHOT | SA_ONSTACK | SA_SIGINFO; + sigaction (SIGSEGV, &s, NULL); + fn2 (); + return 0; +} + +static int __attribute__((noinline)) fn0 () +{ + char dummy __attribute__((cleanup (handler))); + fn1 (); + null = 0; + return 0; +} + +int main() +{ + fn0 (); + abort (); +} -- cgit v1.1