1/* { dg-do run { target hppa*-*-hpux* *-*-linux* powerpc*-*-darwin* *-*-darwin[912]* } } */ 2/* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */ 3/* Verify that cleanups work with exception handling through realtime 4 signal frames. */ 5 6#include <unwind.h> 7#include <stdlib.h> 8#include <signal.h> 9#include <string.h> 10 11static _Unwind_Reason_Code 12force_unwind_stop (int version, _Unwind_Action actions, 13 _Unwind_Exception_Class exc_class, 14 struct _Unwind_Exception *exc_obj, 15 struct _Unwind_Context *context, 16 void *stop_parameter) 17{ 18 if (actions & _UA_END_OF_STACK) 19 abort (); 20 return _URC_NO_REASON; 21} 22 23static void force_unwind () 24{ 25 struct _Unwind_Exception *exc 26 = (struct _Unwind_Exception *) malloc (sizeof (*exc)); 27 memset (&exc->exception_class, 0, sizeof (exc->exception_class)); 28 exc->exception_cleanup = 0; 29 30#ifndef __USING_SJLJ_EXCEPTIONS__ 31 _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); 32#else 33 _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0); 34#endif 35 36 abort (); 37} 38 39int count; 40char *null; 41 42static void counter (void *p __attribute__((unused))) 43{ 44 ++count; 45} 46 47static void handler (void *p __attribute__((unused))) 48{ 49 if (count != 2) 50 abort (); 51 exit (0); 52} 53 54static int __attribute__((noinline)) fn5 () 55{ 56 char dummy __attribute__((cleanup (counter))); 57 force_unwind (); 58 return 0; 59} 60 61static void fn4 (int sig, siginfo_t *info, void *ctx) 62{ 63 char dummy __attribute__((cleanup (counter))); 64 fn5 (); 65 null = NULL; 66} 67 68static void fn3 () 69{ 70 abort (); 71} 72 73static int __attribute__((noinline)) fn2 () 74{ 75 *null = 0; 76 fn3 (); 77 return 0; 78} 79 80static int __attribute__((noinline)) fn1 () 81{ 82 struct sigaction s; 83 sigemptyset (&s.sa_mask); 84 s.sa_sigaction = fn4; 85 s.sa_flags = SA_RESETHAND | SA_SIGINFO; 86 sigaction (SIGSEGV, &s, NULL); 87 sigaction (SIGBUS, &s, NULL); 88 fn2 (); 89 return 0; 90} 91 92static int __attribute__((noinline)) fn0 () 93{ 94 char dummy __attribute__((cleanup (handler))); 95 fn1 (); 96 null = 0; 97 return 0; 98} 99 100int main() 101{ 102 fn0 (); 103 abort (); 104} 105