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