1/* { dg-do run { target hppa*-*-hpux* *-*-linux* powerpc*-*-darwin* } } */ 2/* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */ 3/* Verify that cleanups work with exception handling through signal 4 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 = malloc (sizeof (*exc)); 26 memset (&exc->exception_class, 0, sizeof (exc->exception_class)); 27 exc->exception_cleanup = 0; 28 29#ifndef __USING_SJLJ_EXCEPTIONS__ 30 _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); 31#else 32 _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0); 33#endif 34 35 abort (); 36} 37 38int count; 39char *null; 40 41static void counter (void *p __attribute__((unused))) 42{ 43 ++count; 44} 45 46static void handler (void *p __attribute__((unused))) 47{ 48 if (count != 2) 49 abort (); 50 exit (0); 51} 52 53static int __attribute__((noinline)) fn5 () 54{ 55 char dummy __attribute__((cleanup (counter))); 56 force_unwind (); 57 return 0; 58} 59 60static void fn4 (int sig) 61{ 62 char dummy __attribute__((cleanup (counter))); 63 fn5 (); 64 null = NULL; 65} 66 67static void fn3 () 68{ 69 abort (); 70} 71 72static int __attribute__((noinline)) fn2 () 73{ 74 *null = 0; 75 fn3 (); 76 return 0; 77} 78 79static int __attribute__((noinline)) fn1 () 80{ 81 signal (SIGSEGV, fn4); 82 signal (SIGBUS, fn4); 83 fn2 (); 84 return 0; 85} 86 87static int __attribute__((noinline)) fn0 () 88{ 89 char dummy __attribute__((cleanup (handler))); 90 fn1 (); 91 null = 0; 92 return 0; 93} 94 95int main() 96{ 97 fn0 (); 98 abort (); 99} 100