(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
cleanup-13.c
       1  /* This test is expected to FAIL to compile with
       2     -fcompare-debug -fno-asynchronous-unwind-tables -fno-exceptions
       3     because in that case, the __GCC_HAVE_DWARF2_CFI_ASM macro is only
       4     defined during -g compilation and not defined with -g0.  */
       5  /* HP-UX libunwind.so doesn't provide _UA_END_OF_STACK */
       6  /* { dg-do run } */
       7  /* { dg-options "-fexceptions" } */
       8  /* { dg-skip-if "" { "ia64-*-hpux11.*" } } */
       9  /* { dg-skip-if "" { ! nonlocal_goto } } */
      10  /* { dg-require-effective-target exceptions } */
      11  /* Verify DW_OP_* handling in the unwinder.  */
      12  
      13  #include <unwind.h>
      14  #include <stdlib.h>
      15  #include <string.h>
      16  
      17  /* #define OP_addr(x) 0x06, ... */
      18  #define OP_deref 0x06,
      19  #define SLEB128(x) (x)&0x7f	/* Assume here the value is -0x40 ... 0x3f.  */
      20  #define ULEB128(x) (x)&0x7f	/* Assume here the value is 0 ... 0x7f.  */
      21  #define VAL1(x) (x)&0xff
      22  #if defined (__BIG_ENDIAN__)
      23  #define VAL2(x) ((x)>>8)&0xff,(x)&0xff
      24  #define VAL4(x) ((x)>>24)&0xff,((x)>>16)&0xff,((x)>>8)&0xff,(x)&0xff
      25  #define VAL8(x) ((x)>>56)&0xff,((x)>>48)&0xff,((x)>>40)&0xff,((x)>>32)&0xff,((x)>>24)&0xff,((x)>>16)&0xff,((x)>>8)&0xff,(x)&0xff
      26  #elif defined(__LITTLE_ENDIAN__) || defined(__x86_64__) || defined(__i386__)
      27  #define VAL2(x) (x)&0xff,((x)>>8)&0xff
      28  #define VAL4(x) (x)&0xff,((x)>>8)&0xff,((x)>>16)&0xff,((x)>>24)&0xff
      29  #define VAL8(x) (x)&0xff,((x)>>8)&0xff,((x)>>16)&0xff,((x)>>24)&0xff,((x)>>32)&0xff,((x)>>40)&0xff,((x)>>48)&0xff,((x)>>56)&0xff
      30  #endif
      31  #define OP_const1u(x) 0x08,VAL1(x),
      32  #define OP_const1s(x) 0x09,VAL1(x),
      33  #define OP_const2u(x) 0x0a,VAL2(x),
      34  #define OP_const2s(x) 0x0b,VAL2(x),
      35  #define OP_const4u(x) 0x0c,VAL4(x),
      36  #define OP_const4s(x) 0x0d,VAL4(x),
      37  #define OP_const8u(x) 0x0e,VAL8(x),
      38  #define OP_const8s(x) 0x0f,VAL8(x),
      39  #define OP_constu(x) 0x10,ULEB128(x),
      40  #define OP_consts(x) 0x11,SLEB128(x),
      41  #define OP_dup 0x12,
      42  #define OP_drop 0x13,
      43  #define OP_over 0x14,
      44  #define OP_pick(x) 0x15,VAL1(x),
      45  #define OP_swap 0x16,
      46  #define OP_rot 0x17,
      47  #define OP_xderef 0x18,
      48  #define OP_abs 0x19,
      49  #define OP_and 0x1a,
      50  #define OP_div 0x1b,
      51  #define OP_minus 0x1c,
      52  #define OP_mod 0x1d,
      53  #define OP_mul 0x1e,
      54  #define OP_neg 0x1f,
      55  #define OP_not 0x20,
      56  #define OP_or 0x21,
      57  #define OP_plus 0x22,
      58  #define OP_plus_uconst(x) 0x23,ULEB128(x),
      59  #define OP_shl 0x24,
      60  #define OP_shr 0x25,
      61  #define OP_shra 0x26,
      62  #define OP_xor 0x27,
      63  #define OP_bra(x) 0x28,VAL2(x),
      64  #define OP_eq 0x29,
      65  #define OP_ge 0x2a,
      66  #define OP_gt 0x2b,
      67  #define OP_le 0x2c,
      68  #define OP_lt 0x2d,
      69  #define OP_ne 0x2e,
      70  #define OP_skip(x) 0x2f,VAL2(x),
      71  #define OP_lit0 0x30,
      72  #define OP_lit1 0x31,
      73  #define OP_lit2 0x32,
      74  #define OP_lit3 0x33,
      75  #define OP_lit4 0x34,
      76  #define OP_lit5 0x35,
      77  #define OP_lit6 0x36,
      78  #define OP_lit7 0x37,
      79  #define OP_lit8 0x38,
      80  #define OP_lit9 0x39,
      81  #define OP_lit10 0x3a,
      82  #define OP_lit11 0x3b,
      83  #define OP_lit12 0x3c,
      84  #define OP_lit13 0x3d,
      85  #define OP_lit14 0x3e,
      86  #define OP_lit15 0x3f,
      87  #define OP_lit16 0x40,
      88  #define OP_lit17 0x41,
      89  #define OP_lit18 0x42,
      90  #define OP_lit19 0x43,
      91  #define OP_lit20 0x44,
      92  #define OP_lit21 0x45,
      93  #define OP_lit22 0x46,
      94  #define OP_lit23 0x47,
      95  #define OP_lit24 0x48,
      96  #define OP_lit25 0x49,
      97  #define OP_lit26 0x4a,
      98  #define OP_lit27 0x4b,
      99  #define OP_lit28 0x4c,
     100  #define OP_lit29 0x4d,
     101  #define OP_lit30 0x4e,
     102  #define OP_lit31 0x4f,
     103  #define OP_reg0 0x50,
     104  #define OP_reg1 0x51,
     105  #define OP_reg2 0x52,
     106  #define OP_reg3 0x53,
     107  #define OP_reg4 0x54,
     108  #define OP_reg5 0x55,
     109  #define OP_reg6 0x56,
     110  #define OP_reg7 0x57,
     111  #define OP_reg8 0x58,
     112  #define OP_reg9 0x59,
     113  #define OP_reg10 0x5a,
     114  #define OP_reg11 0x5b,
     115  #define OP_reg12 0x5c,
     116  #define OP_reg13 0x5d,
     117  #define OP_reg14 0x5e,
     118  #define OP_reg15 0x5f,
     119  #define OP_reg16 0x60,
     120  #define OP_reg17 0x61,
     121  #define OP_reg18 0x62,
     122  #define OP_reg19 0x63,
     123  #define OP_reg20 0x64,
     124  #define OP_reg21 0x65,
     125  #define OP_reg22 0x66,
     126  #define OP_reg23 0x67,
     127  #define OP_reg24 0x68,
     128  #define OP_reg25 0x69,
     129  #define OP_reg26 0x6a,
     130  #define OP_reg27 0x6b,
     131  #define OP_reg28 0x6c,
     132  #define OP_reg29 0x6d,
     133  #define OP_reg30 0x6e,
     134  #define OP_reg31 0x6f,
     135  #define OP_breg0(x) 0x70,SLEB128(x),
     136  #define OP_breg1(x) 0x71,SLEB128(x),
     137  #define OP_breg2(x) 0x72,SLEB128(x),
     138  #define OP_breg3(x) 0x73,SLEB128(x),
     139  #define OP_breg4(x) 0x74,SLEB128(x),
     140  #define OP_breg5(x) 0x75,SLEB128(x),
     141  #define OP_breg6(x) 0x76,SLEB128(x),
     142  #define OP_breg7(x) 0x77,SLEB128(x),
     143  #define OP_breg8(x) 0x78,SLEB128(x),
     144  #define OP_breg9(x) 0x79,SLEB128(x),
     145  #define OP_breg10(x) 0x7a,SLEB128(x),
     146  #define OP_breg11(x) 0x7b,SLEB128(x),
     147  #define OP_breg12(x) 0x7c,SLEB128(x),
     148  #define OP_breg13(x) 0x7d,SLEB128(x),
     149  #define OP_breg14(x) 0x7e,SLEB128(x),
     150  #define OP_breg15(x) 0x7f,SLEB128(x),
     151  #define OP_breg16(x) 0x80,SLEB128(x),
     152  #define OP_breg17(x) 0x81,SLEB128(x),
     153  #define OP_breg18(x) 0x82,SLEB128(x),
     154  #define OP_breg19(x) 0x83,SLEB128(x),
     155  #define OP_breg20(x) 0x84,SLEB128(x),
     156  #define OP_breg21(x) 0x85,SLEB128(x),
     157  #define OP_breg22(x) 0x86,SLEB128(x),
     158  #define OP_breg23(x) 0x87,SLEB128(x),
     159  #define OP_breg24(x) 0x88,SLEB128(x),
     160  #define OP_breg25(x) 0x89,SLEB128(x),
     161  #define OP_breg26(x) 0x8a,SLEB128(x),
     162  #define OP_breg27(x) 0x8b,SLEB128(x),
     163  #define OP_breg28(x) 0x8c,SLEB128(x),
     164  #define OP_breg29(x) 0x8d,SLEB128(x),
     165  #define OP_breg30(x) 0x8e,SLEB128(x),
     166  #define OP_breg31(x) 0x8f,SLEB128(x),
     167  #define OP_regx(x) 0x90,SLEB128(x),
     168  #define OP_fbreg(x) 0x91,SLEB128(x),
     169  #define OP_bregx(x,y) 0x92,ULEB128(x),SLEB128(y),
     170  #define OP_piece(x) 0x93,ULEB128(x),
     171  #define OP_deref_size(x) 0x94,VAL1(x),
     172  #define OP_xderef_size(x) 0x95,VAL1(x),
     173  #define OP_nop 0x96,
     174  #define OP_nop_termination 0x96
     175  #define OP_push_object_address 0x97,
     176  #define OP_call2(x) 0x98,VAL2(x),
     177  #define OP_call4(x) 0x99,VAL4(x),
     178  /* #define OP_call_ref(x) 0x9a,... */
     179  #define OP_form_tls_address(x) 0x9b,
     180  #define OP_call_frame_cfa 0x9c,
     181  #define OP_bit_piece(x) 0x9d,ULEB128(x),
     182  /* #define OP_implicit_value(x...) 0x9e,... */
     183  #define OP_stack_value 0x9f,
     184  #define OP_GNU_push_tls_address 0xe0,
     185  /* #define OP_GNU_encoded_addr(x...) 0xf1, */
     186  
     187  #define ASSERT_TOS_NON0 OP_bra(3) OP_skip(-3)
     188  #define ASSERT_TOS_0 OP_lit0 OP_eq ASSERT_TOS_NON0
     189  
     190  /* Initially there is CFA value on the stack, we want to
     191     keep it there at the end.  */
     192  #define CFI_PROGRAM \
     193  OP_lit0 OP_nop ASSERT_TOS_0						\
     194  OP_lit1 ASSERT_TOS_NON0							\
     195  OP_lit1 OP_const1u(1) OP_eq ASSERT_TOS_NON0				\
     196  OP_lit16 OP_const2u(16) OP_eq ASSERT_TOS_NON0				\
     197  OP_lit31 OP_const4u(31) OP_ne ASSERT_TOS_0				\
     198  OP_lit1 OP_neg OP_const1s(-1) OP_eq ASSERT_TOS_NON0			\
     199  OP_lit16 OP_neg OP_const2s(-16) OP_ne ASSERT_TOS_0			\
     200  OP_lit31 OP_const4s(-31) OP_neg OP_ne ASSERT_TOS_0			\
     201  OP_lit7 OP_dup OP_plus_uconst(2) OP_lit9 OP_eq ASSERT_TOS_NON0		\
     202    OP_lit7 OP_eq ASSERT_TOS_NON0						\
     203  OP_lit20 OP_lit1 OP_drop OP_lit20 OP_eq ASSERT_TOS_NON0			\
     204  OP_lit17 OP_lit19 OP_over OP_lit17 OP_eq ASSERT_TOS_NON0		\
     205    OP_lit19 OP_eq ASSERT_TOS_NON0 OP_lit17 OP_eq ASSERT_TOS_NON0		\
     206  OP_lit1 OP_lit2 OP_lit3 OP_lit4 OP_pick(2) OP_lit2 OP_eq ASSERT_TOS_NON0\
     207    OP_lit4 OP_eq ASSERT_TOS_NON0 OP_lit3 OP_eq ASSERT_TOS_NON0		\
     208    OP_pick(0) OP_lit2 OP_eq ASSERT_TOS_NON0				\
     209    OP_lit2 OP_eq ASSERT_TOS_NON0 OP_lit1 OP_eq ASSERT_TOS_NON0		\
     210  OP_lit6 OP_lit12 OP_swap OP_lit6 OP_eq ASSERT_TOS_NON0			\
     211    OP_lit12 OP_eq ASSERT_TOS_NON0					\
     212  OP_lit7 OP_lit8 OP_lit9 OP_rot OP_lit8 OP_eq ASSERT_TOS_NON0		\
     213    OP_lit7 OP_eq ASSERT_TOS_NON0 OP_lit9 OP_eq ASSERT_TOS_NON0		\
     214  OP_lit7 OP_abs OP_lit7 OP_eq ASSERT_TOS_NON0				\
     215  OP_const1s(-123) OP_abs OP_const1u(123) OP_eq ASSERT_TOS_NON0		\
     216  OP_lit3 OP_lit6 OP_and OP_lit2 OP_eq ASSERT_TOS_NON0			\
     217  OP_lit3 OP_lit6 OP_or OP_lit7 OP_eq ASSERT_TOS_NON0			\
     218  OP_lit17 OP_lit2 OP_minus OP_lit15 OP_eq ASSERT_TOS_NON0		\
     219  /* Divide is signed truncating toward zero.  */				\
     220  OP_const1s(-6) OP_const1s(-2) OP_div OP_lit3 OP_eq ASSERT_TOS_NON0	\
     221  OP_const1s(-7) OP_const1s(3) OP_div OP_const1s(-2)			\
     222    OP_eq ASSERT_TOS_NON0							\
     223  /* Modulo is unsigned.  */						\
     224  OP_const1s(-6) OP_const1s(-4) OP_mod OP_const1s(-6)			\
     225    OP_eq ASSERT_TOS_NON0							\
     226  OP_const1s(-6) OP_lit4 OP_mod OP_lit2 OP_eq ASSERT_TOS_NON0		\
     227  OP_lit6 OP_const1s(-4) OP_mod OP_lit6 OP_eq ASSERT_TOS_NON0		\
     228  /* Signed modulo can be implemented using "over over div mul minus".  */\
     229  OP_const1s(-6) OP_const1s(-4) OP_over OP_over OP_div OP_mul OP_minus	\
     230    OP_const1s(-2) OP_eq ASSERT_TOS_NON0					\
     231  OP_const1s(-7) OP_lit3 OP_over OP_over OP_div OP_mul OP_minus		\
     232    OP_const1s(-1) OP_eq ASSERT_TOS_NON0					\
     233  OP_lit7 OP_const1s(-3) OP_over OP_over OP_div OP_mul OP_minus		\
     234    OP_lit1 OP_eq ASSERT_TOS_NON0						\
     235  OP_lit16 OP_lit31 OP_plus_uconst(1) OP_mul OP_const2u(512)		\
     236    OP_eq ASSERT_TOS_NON0							\
     237  OP_lit5 OP_not OP_lit31 OP_and OP_lit26 OP_eq ASSERT_TOS_NON0		\
     238  OP_lit12 OP_lit31 OP_plus OP_const1u(43) OP_eq ASSERT_TOS_NON0		\
     239  OP_const1s(-6) OP_lit2 OP_plus OP_const1s(-4) OP_eq ASSERT_TOS_NON0	\
     240  OP_const1s(-6) OP_plus_uconst(3) OP_const1s(-3) OP_eq ASSERT_TOS_NON0	\
     241  OP_lit16 OP_lit4 OP_shl OP_const2u(256) OP_eq ASSERT_TOS_NON0		\
     242  OP_lit16 OP_lit3 OP_shr OP_lit2 OP_eq ASSERT_TOS_NON0			\
     243  OP_const1s(-16) OP_lit3 OP_shra OP_const1s(-2) OP_eq ASSERT_TOS_NON0	\
     244  OP_lit3 OP_lit6 OP_xor OP_lit5 OP_eq ASSERT_TOS_NON0			\
     245  OP_lit3 OP_lit6 OP_le ASSERT_TOS_NON0					\
     246  OP_lit3 OP_lit3 OP_le ASSERT_TOS_NON0					\
     247  OP_lit6 OP_lit3 OP_le ASSERT_TOS_0					\
     248  OP_lit3 OP_lit6 OP_lt ASSERT_TOS_NON0					\
     249  OP_lit3 OP_lit3 OP_lt ASSERT_TOS_0					\
     250  OP_lit6 OP_lit3 OP_lt ASSERT_TOS_0					\
     251  OP_lit3 OP_lit6 OP_ge ASSERT_TOS_0					\
     252  OP_lit3 OP_lit3 OP_ge ASSERT_TOS_NON0					\
     253  OP_lit6 OP_lit3 OP_ge ASSERT_TOS_NON0					\
     254  OP_lit3 OP_lit6 OP_gt ASSERT_TOS_0					\
     255  OP_lit3 OP_lit3 OP_gt ASSERT_TOS_0					\
     256  OP_lit6 OP_lit3 OP_gt ASSERT_TOS_NON0					\
     257  OP_const1s(-6) OP_lit1 OP_shr OP_lit0 OP_gt ASSERT_TOS_NON0		\
     258  OP_const1s(-6) OP_lit1 OP_shra OP_lit0 OP_lt ASSERT_TOS_NON0
     259  
     260  #define CFI_ESCAPE_VAL_2(VALUES...) #VALUES
     261  #define CFI_ESCAPE_VAL_1(VALUES...) CFI_ESCAPE_VAL_2(VALUES)
     262  #define CFI_ESCAPE_VAL(VALUES...) CFI_ESCAPE_VAL_1(VALUES)
     263  #define CFI_ESCAPE do { } while (0)
     264  #define CFI_ARCH_PROGRAM OP_nop_termination
     265  #ifdef __GCC_HAVE_DWARF2_CFI_ASM
     266  #if defined (__x86_64__)
     267  #undef CFI_ESCAPE
     268  #undef CFI_ARCH_PROGRAM
     269  #define CFI_ARCH_PROGRAM CFI_PROGRAM OP_lit8 OP_minus OP_nop_termination
     270  unsigned char cfi_arch_program[] = { CFI_ARCH_PROGRAM };
     271  extern char verify_it[sizeof (cfi_arch_program) - 0x80 < 0x3f80 ? 1 : -1];
     272  /* DW_CFA_expression %rip, uleb128(l2-l1), l1: program DW_OP_lit8 DW_OP_minus DW_OP_nop l2: */
     273  #define CFI_ESCAPE \
     274    asm volatile (".cfi_escape 0x10, 0x10, (%P0&0x7f)+0x80, %P0>>7, " \
     275  		CFI_ESCAPE_VAL (CFI_ARCH_PROGRAM) \
     276  		: : "i" (sizeof (cfi_arch_program)))
     277  #elif defined (__i386__)
     278  #undef CFI_ESCAPE
     279  #undef CFI_ARCH_PROGRAM
     280  #define CFI_ARCH_PROGRAM CFI_PROGRAM OP_lit4 OP_minus OP_nop_termination
     281  unsigned char cfi_arch_program[] = { CFI_ARCH_PROGRAM };
     282  extern char verify_it[sizeof (cfi_arch_program) - 0x80 < 0x3f80 ? 1 : -1];
     283  /* DW_CFA_expression %eip, uleb128(l2-l1), l1: program DW_OP_lit4 DW_OP_minus DW_OP_nop l2: */
     284  #define CFI_ESCAPE \
     285    asm volatile (".cfi_escape 0x10, 8, (%P0&0x7f)+0x80, %P0>>7, " \
     286  		CFI_ESCAPE_VAL (CFI_ARCH_PROGRAM) \
     287  		: : "i" (sizeof (cfi_arch_program)))
     288  #endif
     289  #endif
     290  static _Unwind_Reason_Code
     291  force_unwind_stop (int version, _Unwind_Action actions,
     292  		   _Unwind_Exception_Class exc_class,
     293  		   struct _Unwind_Exception *exc_obj,
     294  		   struct _Unwind_Context *context,
     295  		   void *stop_parameter)
     296  {
     297    if (actions & _UA_END_OF_STACK)
     298      abort ();
     299    return _URC_NO_REASON;
     300  }
     301  
     302  static void force_unwind ()
     303  {
     304    struct _Unwind_Exception *exc = malloc (sizeof (*exc));
     305    memset (&exc->exception_class, 0, sizeof (exc->exception_class));
     306    exc->exception_cleanup = 0;
     307  
     308  #ifndef __USING_SJLJ_EXCEPTIONS__
     309    _Unwind_ForcedUnwind (exc, force_unwind_stop, 0);
     310  #else
     311    _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0);
     312  #endif
     313  
     314    abort ();
     315  }
     316  
     317  static void handler (void *p __attribute__((unused)))
     318  {
     319    exit (0);
     320  }
     321  
     322  __attribute__((noinline)) static void callme ()
     323  {
     324    CFI_ESCAPE;
     325    force_unwind ();
     326  }
     327  
     328  __attribute__((noinline)) static void doit ()
     329  {
     330    char dummy __attribute__((cleanup (handler)));
     331    callme ();
     332  }
     333  
     334  int main()
     335  { 
     336    doit ();
     337    abort ();
     338  }