OSDN Git Service

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