(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
i386/
cleanup-2.c
       1  /* { dg-do run { target { *-*-linux* && { ! ia32 } } } } */
       2  /* { dg-options "-fexceptions -fnon-call-exceptions -fasynchronous-unwind-tables -O2 -fno-stack-protector" } */
       3  /* Test complex CFA value expressions.  */
       4  
       5  #include <unwind.h>
       6  #include <stdlib.h>
       7  #include <stddef.h>
       8  #include <string.h>
       9  #include <stdio.h>
      10  #include <unistd.h>
      11  
      12  static _Unwind_Reason_Code
      13  force_unwind_stop (int version, _Unwind_Action actions,
      14  		   _Unwind_Exception_Class exc_class,
      15  		   struct _Unwind_Exception *exc_obj,
      16  		   struct _Unwind_Context *context,
      17  		   void *stop_parameter)
      18  {
      19    if (actions & _UA_END_OF_STACK)
      20      abort ();
      21    return _URC_NO_REASON;
      22  }
      23  
      24  static void
      25  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    _Unwind_ForcedUnwind (exc, force_unwind_stop, 0);
      32    abort ();
      33  }
      34  
      35  int count;
      36  
      37  static void
      38  counter (void *p __attribute__((unused)))
      39  {
      40    ++count;
      41  }
      42  
      43  static void
      44  handler (void *p __attribute__((unused)))
      45  {
      46    if (count != 2)
      47      abort ();
      48    _exit (0);
      49  }
      50  
      51  static void
      52  __attribute__((noinline))
      53  check (intptr_t p)
      54  {
      55    if ((p & 15) != 0)
      56      abort ();
      57  }
      58  
      59  static int __attribute__((noinline))
      60  fn5 (void)
      61  {
      62    char dummy __attribute__((cleanup (counter)));
      63    force_unwind ();
      64    return 0;
      65  }
      66  
      67  void
      68  bar (void)
      69  {
      70    char dummy __attribute__((cleanup (counter)));
      71    unsigned long tmp[4] __attribute__((aligned(16)));
      72    check ((intptr_t) tmp);
      73    fn5 ();
      74  }
      75  
      76  void __attribute__((noinline))
      77  foo (int x)
      78  {
      79    char buf[256];
      80  #ifdef __x86_64__
      81    __asm (
      82  	"testl	%0, %0\n\t"
      83  	"jnz	1f\n\t"
      84  	".subsection 1\n\t"
      85  	".type	_L_mutex_lock_%=, @function\n"
      86  "_L_mutex_lock_%=:\n"
      87  "1:\t"	"leaq	%1, %%rdi\n"
      88  "2:\t"	"subq	$136, %%rsp\n"
      89  "3:\t"	"call	bar\n"
      90  "4:\t"	"addq	$136, %%rsp\n"
      91  "5:\t"	"jmp	21f\n"
      92  "6:\t"	".size _L_mutex_lock_%=, .-_L_mutex_lock_%=\n\t"
      93  	".previous\n\t"
      94  	".section	.eh_frame,\"a\",@progbits\n"
      95  "7:\t"	".long	9f-8f	# Length of Common Information Entry\n"
      96  "8:\t"	".long	0x0	# CIE Identifier Tag\n\t"
      97  	".byte	0x1	# CIE Version\n\t"
      98  	".ascii \"zR\\0\"	# CIE Augmentation\n\t"
      99  	".uleb128 0x1	# CIE Code Alignment Factor\n\t"
     100  	".sleb128 -8	# CIE Data Alignment Factor\n\t"
     101  	".byte	0x10	# CIE RA Column\n\t"
     102  	".uleb128 0x1	# Augmentation size\n\t"
     103  	".byte	0x1b	# FDE Encoding (pcrel sdata4)\n\t"
     104  	".byte	0xc	# DW_CFA_def_cfa\n\t"
     105  	".uleb128 0x7\n\t"
     106  	".uleb128 0x0\n\t"
     107  	".align 8\n"
     108  "9:\t"	".long	20f-10f	# FDE Length\n"
     109  "10:\t"	".long	10b-7b	# FDE CIE offset\n\t"
     110  	".long	1b-.	# FDE initial location\n\t"
     111  	".long	6b-1b	# FDE address range\n\t"
     112  	".uleb128 0x0	# Augmentation size\n\t"
     113  	/* This CFA expression computes the address right
     114  	   past the jnz instruction above, from %rip somewhere
     115  	   within the _L_mutex_lock_%= subsection.  */
     116  	".byte	0x16	# DW_CFA_val_expression\n\t"
     117  	".uleb128 0x10\n\t"
     118  	".uleb128 19f-11f\n"
     119  "11:\t"	".byte	0x80	# DW_OP_breg16\n\t"
     120  	".sleb128 0\n"
     121  "12:\t"	".byte	0x12	# DW_OP_dup\n\t"
     122  	".byte	0x94	# DW_OP_deref_size\n\t"
     123  	".byte	1\n\t"
     124  	".byte	0x12	# DW_OP_dup\n\t"
     125  	".byte	0x08	# DW_OP_const1u\n\t"
     126  	".byte	0x48\n\t"
     127  	".byte	0x2e	# DW_OP_ne\n\t"
     128  	".byte	0x28	# DW_OP_bra\n\t"
     129  	".2byte	16f-13f\n"
     130  "13:\t"	".byte	0x13	# DW_OP_drop\n\t"
     131  	".byte	0x23	# DW_OP_plus_uconst\n\t"
     132  	".uleb128 1\n\t"
     133  	".byte	0x12	# DW_OP_dup\n\t"
     134  	".byte	0x94	# DW_OP_deref_size\n\t"
     135  	".byte	1\n\t"
     136  	".byte	0x08	# DW_OP_const1u\n\t"
     137  	".byte	0x81\n\t"
     138  	".byte	0x2e	# DW_OP_ne\n\t"
     139  	".byte	0x28	# DW_OP_bra\n\t"
     140  	".2byte	15f-14f\n"
     141  "14:\t"	".byte	0x23	# DW_OP_plus_uconst\n\t"
     142  	".uleb128 3b-2b-1\n\t"
     143  	".byte	0x2f	# DW_OP_skip\n\t"
     144  	".2byte	12b-15f\n"
     145  "15:\t"	".byte	0x23	# DW_OP_plus_uconst\n\t"
     146  	".uleb128 2b-1b-1\n\t"
     147  	".byte	0x2f	# DW_OP_skip\n\t"
     148  	".2byte	12b-16f\n"
     149  "16:\t"	".byte	0x08	# DW_OP_const1u\n\t"
     150  	".byte	0xe8\n\t"
     151  	".byte	0x2e	# DW_OP_ne\n\t"
     152  	".byte	0x28	# DW_OP_bra\n\t"
     153  	".2byte	18f-17f\n"
     154  "17:\t"	".byte	0x23	# DW_OP_plus_uconst\n\t"
     155  	".uleb128 4b-3b\n\t"
     156  	".byte	0x2f	# DW_OP_skip\n\t"
     157  	".2byte	12b-18f\n"
     158  "18:\t"	".byte	0x23	# DW_OP_plus_uconst\n\t"
     159  	".uleb128 1\n\t"
     160  	".byte	0x12	# DW_OP_dup\n\t"
     161  	".byte	0x94	# DW_OP_deref_size\n\t"
     162  	".byte	4\n\t"
     163  	".byte	0x08	# DW_OP_const1u\n\t"
     164  	".byte	72 - (6b-5b) * 8 # (6b-5b) == 5 ? 32 : 56\n\t"
     165  	".byte	0x24	# DW_OP_shl\n\t"
     166  	".byte	0x08	# DW_OP_const1u\n\t"
     167  	".byte	72 - (6b-5b) * 8 # (6b-5b) == 5 ? 32 : 56\n\t"
     168  	".byte	0x26	# DW_OP_shra\n\t"
     169  	".byte	0x22	# DW_OP_plus\n\t"
     170  	".byte	0x23	# DW_OP_plus_uconst\n\t"
     171  	".uleb128 6b-5b-1\n"
     172  "19:\t"	".byte	0x40 + (3b-1b) # DW_CFA_advance_loc\n\t"
     173  	".byte	0xe	# DW_CFA_def_cfa_offset\n\t"
     174  	".uleb128 136\n\t"
     175  	".byte	0x40 + (5b-3b) # DW_CFA_advance_loc\n\t"
     176  	".byte	0xe	# DW_CFA_def_cfa_offset\n\t"
     177  	".uleb128 0\n\t"
     178  	".align 8\n"
     179  "20:\t"	".previous\n"
     180  "21:"
     181  	: : "r" (x), "m" (x), "r" (buf)
     182  	: "memory", "rax", "rdx", "rcx", "rsi", "rdi",
     183  	  "r8", "r9", "r10", "r11");
     184  #else
     185  # error Unsupported test architecture
     186  #endif
     187  }
     188  
     189  static int __attribute__((noinline))
     190  fn2 (void)
     191  {
     192    foo (3);
     193    return 0;
     194  }
     195  
     196  static int __attribute__((noinline))
     197  fn1 (void)
     198  {
     199    fn2 ();
     200    return 0;
     201  }
     202  
     203  static void *
     204  fn0 (void)
     205  {
     206    char dummy __attribute__((cleanup (handler)));
     207    fn1 ();
     208    return 0;
     209  }
     210  
     211  int
     212  main (void)
     213  {
     214    fn0 ();
     215    return 0;
     216  }