Branch data Line data Source code
1 : : /* Exception Handling interface routines.
2 : : Copyright (C) 1996-2024 Free Software Foundation, Inc.
3 : : Contributed by Mike Stump <mrs@cygnus.com>.
4 : :
5 : : This file is part of GCC.
6 : :
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
9 : : Software Foundation; either version 3, or (at your option) any later
10 : : version.
11 : :
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.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along with GCC; see the file COPYING3. If not see
19 : : <http://www.gnu.org/licenses/>. */
20 : :
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
25 : : #define GCC_EXCEPT_H
26 : :
27 : :
28 : : struct function;
29 : : struct eh_region_d;
30 : :
31 : : /* The type of an exception region. */
32 : : enum eh_region_type
33 : : {
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. */
39 : : ERT_CLEANUP,
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
43 : : control is transferred to the appropriate handler. Note that a NULL type
44 : : list is a catch-all handler, and that it will catch *all* exceptions
45 : : including those originating from a different language. */
46 : : ERT_TRY,
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. */
53 : : ERT_ALLOWED_EXCEPTIONS,
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((chain_next("%h.next_lp"))) 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 : :
77 : : /* At the gimple level, the location to which control will be transferred
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. */
87 : : rtx_code_label *landing_pad;
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;
114 : : };
115 : :
116 : : /* Describes one exception region. */
117 : :
118 : : struct GTY(()) eh_region_d
119 : : {
120 : : /* The immediately surrounding region. */
121 : : struct eh_region_d *outer;
122 : :
123 : : /* The list of immediately contained regions. */
124 : : struct eh_region_d *inner;
125 : : struct eh_region_d *next_peer;
126 : :
127 : : /* The index of this region within fun->eh->region_array. */
128 : : int index;
129 : :
130 : : /* Each region does exactly one thing. */
131 : : enum eh_region_type type;
132 : :
133 : : /* Holds the action to perform based on the preceding type. */
134 : : union eh_region_u {
135 : : struct eh_region_u_try {
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;
139 : : } GTY ((tag ("ERT_TRY"))) eh_try;
140 : :
141 : : struct eh_region_u_allowed {
142 : : /* A TREE_LIST of runtime type objects allowed to pass. */
143 : : tree type_list;
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. */
152 : : int filter;
153 : : } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;
154 : :
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 TRY 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
161 : : what termination function is called; it will be decided by the
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;
167 : : } GTY ((desc ("%0.type"))) u;
168 : :
169 : : /* The list of landing pads associated with this region. */
170 : : struct eh_landing_pad_d *landing_pads;
171 : :
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;
176 : :
177 : : /* True if this region should use __cxa_end_cleanup instead
178 : : of _Unwind_Resume. */
179 : : bool use_cxa_end_cleanup;
180 : : };
181 : :
182 : : typedef struct eh_landing_pad_d *eh_landing_pad;
183 : : typedef struct eh_catch_d *eh_catch;
184 : : typedef struct eh_region_d *eh_region;
185 : :
186 : :
187 : :
188 : :
189 : : /* The exception status for each function. */
190 : :
191 : : struct GTY(()) eh_status
192 : : {
193 : : /* The tree of all regions for this function. */
194 : : eh_region region_tree;
195 : :
196 : : /* The same information as an indexable array. */
197 : : vec<eh_region, va_gc> *region_array;
198 : :
199 : : /* The landing pads as an indexable array. */
200 : : vec<eh_landing_pad, va_gc> *lp_array;
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. */
204 : : hash_map<gimple *, int> *GTY(()) throw_stmt_table;
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. */
208 : : vec<tree, va_gc> *ttype_data;
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 {
215 : : vec<tree, va_gc> *GTY((tag ("1"))) arm_eabi;
216 : : vec<uchar, va_gc> *GTY((tag ("0"))) other;
217 : : } GTY ((desc ("targetm.arm_eabi_unwinder"))) ehspec_data;
218 : : };
219 : :
220 : :
221 : : /* Invokes CALLBACK for every exception handler label. Only used by old
222 : : loop hackery; should not be used by new code. */
223 : : extern void for_each_eh_label (void (*) (rtx));
224 : :
225 : : extern void init_eh_for_function (void);
226 : :
227 : : extern void remove_eh_landing_pad (eh_landing_pad);
228 : : extern void remove_eh_handler (eh_region);
229 : : extern void remove_unreachable_eh_regions (sbitmap);
230 : :
231 : : extern bool current_function_has_exception_handlers (void);
232 : : extern void output_function_exception_table (int);
233 : :
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);
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);
245 : : extern rtx expand_builtin_extend_pointer (tree);
246 : :
247 : : typedef tree (*duplicate_eh_regions_map) (tree, void *);
248 : : extern hash_map<void *, void *> *duplicate_eh_regions
249 : : (struct function *, eh_region, int, duplicate_eh_regions_map, void *);
250 : :
251 : : extern void sjlj_emit_function_exit_after (rtx_insn *);
252 : : extern void update_sjlj_context (void);
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 : :
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 *);
273 : :
274 : : extern void verify_eh_tree (struct function *);
275 : : extern void dump_eh_tree (FILE *, struct function *);
276 : : void debug_eh_tree (struct function *);
277 : : extern void add_type_for_runtime (tree);
278 : : extern tree lookup_type_for_runtime (tree);
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);
283 : :
284 : : extern void finish_eh_generation (void);
285 : :
286 : : struct GTY(()) throw_stmt_node {
287 : : gimple *stmt;
288 : : int lp_nr;
289 : : };
290 : :
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> *);
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 *);
302 : :
303 : : /* Pre-order iteration within the eh_region tree. */
304 : :
305 : : inline eh_region
306 : 5625746 : ehr_next (eh_region r, eh_region start)
307 : : {
308 : 5625746 : if (r->inner)
309 : : r = r->inner;
310 : 4202785 : else if (r->next_peer && r != start)
311 : : r = r->next_peer;
312 : : else
313 : : {
314 : 3857442 : do
315 : : {
316 : 3857442 : r = r->outer;
317 : 3857442 : if (r == start)
318 : : return NULL;
319 : : }
320 : 1407441 : 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)
333 : :
334 : : #endif
|