]>
Commit | Line | Data |
---|---|---|
4956d07c | 1 | /* Exception Handling interface routines. |
8d9254fc | 2 | Copyright (C) 1996-2020 Free Software Foundation, Inc. |
4956d07c MS |
3 | Contributed by Mike Stump <mrs@cygnus.com>. |
4 | ||
1322177d | 5 | This file is part of GCC. |
4956d07c | 6 | |
1322177d LB |
7 | GCC is free software; you can redistribute it and/or modify it under |
8 | the terms of the GNU General Public License as published by the Free | |
9dcd6f09 | 9 | Software Foundation; either version 3, or (at your option) any later |
1322177d | 10 | version. |
4956d07c | 11 | |
1322177d LB |
12 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | for more details. | |
4956d07c MS |
16 | |
17 | You should have received a copy of the GNU General Public License | |
9dcd6f09 NC |
18 | along with GCC; see the file COPYING3. If not see |
19 | <http://www.gnu.org/licenses/>. */ | |
4956d07c | 20 | |
3b06d379 SB |
21 | /* No include guards here, but define an include file marker anyway, so |
22 | that the compiler can keep track of where this file is included. This | |
23 | is e.g. used to avoid including this file in front-end specific files. */ | |
24 | #ifndef GCC_EXCEPT_H | |
f1717f8d | 25 | #define GCC_EXCEPT_H |
3b06d379 | 26 | |
9a0d1e1b | 27 | |
f9f6b7df | 28 | struct function; |
1d65f45c | 29 | struct eh_region_d; |
f9f6b7df | 30 | |
24b97832 ILT |
31 | /* The type of an exception region. */ |
32 | enum eh_region_type | |
33 | { | |
1d65f45c RH |
34 | /* CLEANUP regions implement e.g. destructors run when exiting a block. |
35 | They can be generated from both GIMPLE_TRY_FINALLY and GIMPLE_TRY_CATCH | |
36 | nodes. It is expected by the runtime that cleanup regions will *not* | |
37 | resume normal program flow, but will continue propagation of the | |
38 | exception. */ | |
24b97832 | 39 | ERT_CLEANUP, |
1d65f45c RH |
40 | |
41 | /* TRY regions implement catching an exception. The list of types associated | |
42 | with the attached catch handlers is examined in order by the runtime and | |
073a8998 | 43 | control is transferred to the appropriate handler. Note that a NULL type |
1d65f45c RH |
44 | list is a catch-all handler, and that it will catch *all* exceptions |
45 | including those originating from a different language. */ | |
24b97832 | 46 | ERT_TRY, |
1d65f45c RH |
47 | |
48 | /* ALLOWED_EXCEPTIONS regions implement exception filtering, e.g. the | |
49 | throw(type-list) specification that can be added to C++ functions. | |
50 | The runtime examines the thrown exception vs the type list, and if | |
51 | the exception does not match, transfers control to the handler. The | |
52 | normal handler for C++ calls __cxa_call_unexpected. */ | |
24b97832 | 53 | ERT_ALLOWED_EXCEPTIONS, |
1d65f45c RH |
54 | |
55 | /* MUST_NOT_THROW regions prevent all exceptions from propagating. This | |
56 | region type is used in C++ to surround destructors being run inside a | |
57 | CLEANUP region. This differs from an ALLOWED_EXCEPTIONS region with | |
58 | an empty type list in that the runtime is prepared to terminate the | |
59 | program directly. We only generate code for MUST_NOT_THROW regions | |
60 | along control paths that are already handling an exception within the | |
61 | current function. */ | |
62 | ERT_MUST_NOT_THROW | |
63 | }; | |
64 | ||
65 | ||
66 | /* A landing pad for a given exception region. Any transfer of control | |
67 | from the EH runtime to the function happens at a landing pad. */ | |
68 | ||
69 | struct GTY(()) eh_landing_pad_d | |
70 | { | |
71 | /* The linked list of all landing pads associated with the region. */ | |
72 | struct eh_landing_pad_d *next_lp; | |
73 | ||
74 | /* The region with which this landing pad is associated. */ | |
75 | struct eh_region_d *region; | |
76 | ||
073a8998 | 77 | /* At the gimple level, the location to which control will be transferred |
1d65f45c RH |
78 | for this landing pad. There can be both EH and normal edges into the |
79 | block containing the post-landing-pad label. */ | |
80 | tree post_landing_pad; | |
81 | ||
82 | /* At the rtl level, the location to which the runtime will transfer | |
83 | control. This differs from the post-landing-pad in that the target's | |
84 | EXCEPTION_RECEIVER pattern will be expanded here, as well as other | |
85 | bookkeeping specific to exceptions. There must not be normal edges | |
86 | into the block containing the landing-pad label. */ | |
be7457df | 87 | rtx_code_label *landing_pad; |
1d65f45c RH |
88 | |
89 | /* The index of this landing pad within fun->eh->lp_array. */ | |
90 | int index; | |
91 | }; | |
92 | ||
93 | /* A catch handler associated with an ERT_TRY region. */ | |
94 | ||
95 | struct GTY(()) eh_catch_d | |
96 | { | |
97 | /* The double-linked list of all catch handlers for the region. */ | |
98 | struct eh_catch_d *next_catch; | |
99 | struct eh_catch_d *prev_catch; | |
100 | ||
101 | /* A TREE_LIST of runtime type objects that this catch handler | |
102 | will catch, or NULL if all exceptions are caught. */ | |
103 | tree type_list; | |
104 | ||
105 | /* A TREE_LIST of INTEGER_CSTs that correspond to the type_list entries, | |
106 | having been mapped by assign_filter_values. These integers are to be | |
107 | compared against the __builtin_eh_filter value. */ | |
108 | tree filter_list; | |
109 | ||
110 | /* The code that should be executed if this catch handler matches the | |
111 | thrown exception. This label is only maintained until | |
112 | pass_lower_eh_dispatch, at which point it is cleared. */ | |
113 | tree label; | |
24b97832 ILT |
114 | }; |
115 | ||
9994a182 | 116 | /* Describes one exception region. */ |
1d65f45c | 117 | |
7e5487a2 | 118 | struct GTY(()) eh_region_d |
9994a182 DN |
119 | { |
120 | /* The immediately surrounding region. */ | |
7e5487a2 | 121 | struct eh_region_d *outer; |
9994a182 DN |
122 | |
123 | /* The list of immediately contained regions. */ | |
7e5487a2 ILT |
124 | struct eh_region_d *inner; |
125 | struct eh_region_d *next_peer; | |
9994a182 | 126 | |
1d65f45c RH |
127 | /* The index of this region within fun->eh->region_array. */ |
128 | int index; | |
9994a182 DN |
129 | |
130 | /* Each region does exactly one thing. */ | |
24b97832 | 131 | enum eh_region_type type; |
9994a182 DN |
132 | |
133 | /* Holds the action to perform based on the preceding type. */ | |
134 | union eh_region_u { | |
9994a182 | 135 | struct eh_region_u_try { |
1d65f45c RH |
136 | /* The double-linked list of all catch handlers for this region. */ |
137 | struct eh_catch_d *first_catch; | |
138 | struct eh_catch_d *last_catch; | |
9994a182 DN |
139 | } GTY ((tag ("ERT_TRY"))) eh_try; |
140 | ||
9994a182 | 141 | struct eh_region_u_allowed { |
1d65f45c | 142 | /* A TREE_LIST of runtime type objects allowed to pass. */ |
9994a182 | 143 | tree type_list; |
1d65f45c RH |
144 | /* The code that should be executed if the thrown exception does |
145 | not match the type list. This label is only maintained until | |
146 | pass_lower_eh_dispatch, at which point it is cleared. */ | |
147 | tree label; | |
148 | /* The integer that will be passed by the runtime to signal that | |
149 | we should execute the code at LABEL. This integer is assigned | |
150 | by assign_filter_values and is to be compared against the | |
151 | __builtin_eh_filter value. */ | |
9994a182 DN |
152 | int filter; |
153 | } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed; | |
154 | ||
1d65f45c RH |
155 | struct eh_region_u_must_not_throw { |
156 | /* A function decl to be invoked if this region is actually reachable | |
157 | from within the function, rather than implementable from the runtime. | |
158 | The normal way for this to happen is for there to be a CLEANUP region | |
159 | contained within this MUST_NOT_THROW region. Note that if the | |
160 | runtime handles the MUST_NOT_THROW region, we have no control over | |
b8698a0f | 161 | what termination function is called; it will be decided by the |
1d65f45c RH |
162 | personality function in effect for this CIE. */ |
163 | tree failure_decl; | |
164 | /* The location assigned to the call of FAILURE_DECL, if expanded. */ | |
165 | location_t failure_loc; | |
166 | } GTY ((tag ("ERT_MUST_NOT_THROW"))) must_not_throw; | |
9994a182 DN |
167 | } GTY ((desc ("%0.type"))) u; |
168 | ||
1d65f45c RH |
169 | /* The list of landing pads associated with this region. */ |
170 | struct eh_landing_pad_d *landing_pads; | |
9994a182 | 171 | |
1d65f45c RH |
172 | /* EXC_PTR and FILTER values copied from the runtime for this region. |
173 | Each region gets its own psuedos so that if there are nested exceptions | |
174 | we do not overwrite the values of the first exception. */ | |
175 | rtx exc_ptr_reg, filter_reg; | |
384c400a RH |
176 | |
177 | /* True if this region should use __cxa_end_cleanup instead | |
178 | of _Unwind_Resume. */ | |
179 | bool use_cxa_end_cleanup; | |
9994a182 DN |
180 | }; |
181 | ||
1d65f45c RH |
182 | typedef struct eh_landing_pad_d *eh_landing_pad; |
183 | typedef struct eh_catch_d *eh_catch; | |
7e5487a2 | 184 | typedef struct eh_region_d *eh_region; |
1d65f45c | 185 | |
9994a182 | 186 | |
1d65f45c RH |
187 | |
188 | ||
189 | /* The exception status for each function. */ | |
190 | ||
d1b38208 | 191 | struct GTY(()) eh_status |
9994a182 DN |
192 | { |
193 | /* The tree of all regions for this function. */ | |
1d65f45c | 194 | eh_region region_tree; |
9994a182 DN |
195 | |
196 | /* The same information as an indexable array. */ | |
9771b263 | 197 | vec<eh_region, va_gc> *region_array; |
9994a182 | 198 | |
1d65f45c | 199 | /* The landing pads as an indexable array. */ |
9771b263 | 200 | vec<eh_landing_pad, va_gc> *lp_array; |
1d65f45c RH |
201 | |
202 | /* At the gimple level, a mapping from gimple statement to landing pad | |
203 | or must-not-throw region. See record_stmt_eh_region. */ | |
355fe088 | 204 | hash_map<gimple *, int> *GTY(()) throw_stmt_table; |
1d65f45c RH |
205 | |
206 | /* All of the runtime type data used by the function. These objects | |
207 | are emitted to the lang-specific-data-area for the function. */ | |
9771b263 | 208 | vec<tree, va_gc> *ttype_data; |
1d65f45c RH |
209 | |
210 | /* The table of all action chains. These encode the eh_region tree in | |
211 | a compact form for use by the runtime, and is also emitted to the | |
212 | lang-specific-data-area. Note that the ARM EABI uses a different | |
213 | format for the encoding than all other ports. */ | |
214 | union eh_status_u { | |
9771b263 DN |
215 | vec<tree, va_gc> *GTY((tag ("1"))) arm_eabi; |
216 | vec<uchar, va_gc> *GTY((tag ("0"))) other; | |
1d65f45c | 217 | } GTY ((desc ("targetm.arm_eabi_unwinder"))) ehspec_data; |
9994a182 | 218 | }; |
911fdd58 | 219 | |
ce152ef8 | 220 | |
6a58eee9 RH |
221 | /* Invokes CALLBACK for every exception handler label. Only used by old |
222 | loop hackery; should not be used by new code. */ | |
502b8322 | 223 | extern void for_each_eh_label (void (*) (rtx)); |
4956d07c | 224 | |
502b8322 | 225 | extern void init_eh_for_function (void); |
911fdd58 | 226 | |
1d65f45c RH |
227 | extern void remove_eh_landing_pad (eh_landing_pad); |
228 | extern void remove_eh_handler (eh_region); | |
d273b176 | 229 | extern void remove_unreachable_eh_regions (sbitmap); |
e976b8b2 | 230 | |
502b8322 | 231 | extern bool current_function_has_exception_handlers (void); |
b78b513e | 232 | extern void output_function_exception_table (int); |
154bba13 | 233 | |
1d65f45c RH |
234 | extern rtx expand_builtin_eh_pointer (tree); |
235 | extern rtx expand_builtin_eh_filter (tree); | |
236 | extern rtx expand_builtin_eh_copy_values (tree); | |
502b8322 AJ |
237 | extern void expand_builtin_unwind_init (void); |
238 | extern rtx expand_builtin_eh_return_data_regno (tree); | |
239 | extern rtx expand_builtin_extract_return_addr (tree); | |
240 | extern void expand_builtin_init_dwarf_reg_sizes (tree); | |
241 | extern rtx expand_builtin_frob_return_addr (tree); | |
242 | extern rtx expand_builtin_dwarf_sp_column (void); | |
243 | extern void expand_builtin_eh_return (tree, tree); | |
244 | extern void expand_eh_return (void); | |
c76362b4 | 245 | extern rtx expand_builtin_extend_pointer (tree); |
1d65f45c | 246 | |
98f464e0 | 247 | typedef tree (*duplicate_eh_regions_map) (tree, void *); |
b787e7a2 | 248 | extern hash_map<void *, void *> *duplicate_eh_regions |
1d65f45c | 249 | (struct function *, eh_region, int, duplicate_eh_regions_map, void *); |
e976b8b2 | 250 | |
f8b23302 | 251 | extern void sjlj_emit_function_exit_after (rtx_insn *); |
d33606c3 | 252 | extern void update_sjlj_context (void); |
1d65f45c RH |
253 | |
254 | extern eh_region gen_eh_region_cleanup (eh_region); | |
255 | extern eh_region gen_eh_region_try (eh_region); | |
256 | extern eh_region gen_eh_region_allowed (eh_region, tree); | |
257 | extern eh_region gen_eh_region_must_not_throw (eh_region); | |
258 | ||
259 | extern eh_catch gen_eh_region_catch (eh_region, tree); | |
260 | extern eh_landing_pad gen_eh_landing_pad (eh_region); | |
261 | ||
262 | extern eh_region get_eh_region_from_number_fn (struct function *, int); | |
263 | extern eh_region get_eh_region_from_number (int); | |
264 | extern eh_landing_pad get_eh_landing_pad_from_number_fn (struct function*,int); | |
265 | extern eh_landing_pad get_eh_landing_pad_from_number (int); | |
266 | extern eh_region get_eh_region_from_lp_number_fn (struct function *, int); | |
267 | extern eh_region get_eh_region_from_lp_number (int); | |
268 | ||
269 | extern eh_region eh_region_outermost (struct function *, eh_region, eh_region); | |
270 | ||
84f16edb TS |
271 | extern void make_reg_eh_region_note (rtx_insn *insn, int ecf_flags, int lp_nr); |
272 | extern void make_reg_eh_region_note_nothrow_nononlocal (rtx_insn *); | |
1d65f45c | 273 | |
cc7220fd JH |
274 | extern void verify_eh_tree (struct function *); |
275 | extern void dump_eh_tree (FILE *, struct function *); | |
9994a182 | 276 | void debug_eh_tree (struct function *); |
9994a182 DN |
277 | extern void add_type_for_runtime (tree); |
278 | extern tree lookup_type_for_runtime (tree); | |
1d65f45c RH |
279 | extern void assign_filter_values (void); |
280 | ||
281 | extern eh_region get_eh_region_from_rtx (const_rtx); | |
282 | extern eh_landing_pad get_eh_landing_pad_from_rtx (const_rtx); | |
6de9cd9a | 283 | |
dac1fbf8 RG |
284 | extern void finish_eh_generation (void); |
285 | ||
d1b38208 | 286 | struct GTY(()) throw_stmt_node { |
355fe088 | 287 | gimple *stmt; |
1d65f45c | 288 | int lp_nr; |
b4660e5a JH |
289 | }; |
290 | ||
355fe088 TS |
291 | extern hash_map<gimple *, int> *get_eh_throw_stmt_table (struct function *); |
292 | extern void set_eh_throw_stmt_table (function *, hash_map<gimple *, int> *); | |
f9417da1 RG |
293 | |
294 | enum eh_personality_kind { | |
295 | eh_personality_none, | |
296 | eh_personality_any, | |
297 | eh_personality_lang | |
298 | }; | |
299 | ||
300 | extern enum eh_personality_kind | |
301 | function_needs_eh_personality (struct function *); | |
1d65f45c RH |
302 | |
303 | /* Pre-order iteration within the eh_region tree. */ | |
304 | ||
305 | static inline eh_region | |
306 | ehr_next (eh_region r, eh_region start) | |
307 | { | |
308 | if (r->inner) | |
309 | r = r->inner; | |
310 | else if (r->next_peer && r != start) | |
311 | r = r->next_peer; | |
312 | else | |
313 | { | |
314 | do | |
315 | { | |
316 | r = r->outer; | |
317 | if (r == start) | |
318 | return NULL; | |
319 | } | |
320 | while (r->next_peer == NULL); | |
321 | r = r->next_peer; | |
322 | } | |
323 | return r; | |
324 | } | |
325 | ||
326 | #define FOR_ALL_EH_REGION_AT(R, START) \ | |
327 | for ((R) = (START); (R) != NULL; (R) = ehr_next (R, START)) | |
328 | ||
329 | #define FOR_ALL_EH_REGION_FN(R, FN) \ | |
330 | for ((R) = (FN)->eh->region_tree; (R) != NULL; (R) = ehr_next (R, NULL)) | |
331 | ||
332 | #define FOR_ALL_EH_REGION(R) FOR_ALL_EH_REGION_FN (R, cfun) | |
f1717f8d KC |
333 | |
334 | #endif |