summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/cleanup-10.c
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2003-12-19 14:00:53 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2003-12-19 14:00:53 +0000
commit754355026012435084d70a4f074eea9c1774805f (patch)
tree7faf100b24bd243e8eba0de3b6bf9f538ba40ee2 /gcc/testsuite/gcc.dg/cleanup-10.c
parent55a723b13d2c741599667e6b2bf5decc2b603ab4 (diff)
downloadgcc-754355026012435084d70a4f074eea9c1774805f.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@74835 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/testsuite/gcc.dg/cleanup-10.c')
-rw-r--r--gcc/testsuite/gcc.dg/cleanup-10.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/cleanup-10.c b/gcc/testsuite/gcc.dg/cleanup-10.c
new file mode 100644
index 00000000000..39923fdde15
--- /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 <unwind.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+
+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 ();
+}