(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
aarch64/
pr94514.c
       1  /* PR target/94514. Unwind across mixed pac-ret and non-pac-ret frames.  */
       2  /* { dg-do run } */
       3  /* { dg-require-effective-target lp64 } */
       4  /* { dg-options "-fexceptions -O2" } */
       5  
       6  #include <unwind.h>
       7  #include <stdlib.h>
       8  #include <stdio.h>
       9  
      10  #define die() \
      11    do { \
      12      printf ("%s:%d: reached unexpectedly.\n", __FILE__, __LINE__); \
      13      fflush (stdout); \
      14      abort (); \
      15    } while (0)
      16  
      17  static struct _Unwind_Exception exc;
      18  
      19  static _Unwind_Reason_Code
      20  force_unwind_stop (int version, _Unwind_Action actions,
      21                     _Unwind_Exception_Class exc_class,
      22                     struct _Unwind_Exception *exc_obj,
      23                     struct _Unwind_Context *context,
      24                     void *stop_parameter)
      25  {
      26    printf ("%s: CFA: %p PC: %p actions: %d\n",
      27  	  __func__,
      28  	  (void *)_Unwind_GetCFA (context),
      29  	  (void *)_Unwind_GetIP (context),
      30  	  (int)actions);
      31    if (actions & _UA_END_OF_STACK)
      32      die ();
      33    return _URC_NO_REASON;
      34  }
      35  
      36  static void force_unwind (void)
      37  {
      38  #ifndef __USING_SJLJ_EXCEPTIONS__
      39    _Unwind_ForcedUnwind (&exc, force_unwind_stop, 0);
      40  #else
      41    _Unwind_SjLj_ForcedUnwind (&exc, force_unwind_stop, 0);
      42  #endif
      43  }
      44  
      45  __attribute__((noinline, target("branch-protection=pac-ret")))
      46  static void f2_pac_ret (void)
      47  {
      48    force_unwind ();
      49    die ();
      50  }
      51  
      52  __attribute__((noinline, target("branch-protection=none")))
      53  static void f1_no_pac_ret (void)
      54  {
      55    f2_pac_ret ();
      56    die ();
      57  }
      58  
      59  __attribute__((noinline, target("branch-protection=pac-ret")))
      60  static void f0_pac_ret (void)
      61  {
      62    f1_no_pac_ret ();
      63    die ();
      64  }
      65  
      66  static void cleanup_handler (void *p)
      67  {
      68    printf ("%s: Success.\n", __func__);
      69    exit (0);
      70  }
      71  
      72  int main ()
      73  {
      74    char dummy __attribute__((cleanup (cleanup_handler)));
      75    f0_pac_ret ();
      76    die ();
      77  }