1 /* Exception Handling interface routines. 2 Copyright (C) 1996-2018 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(()) 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 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 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 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) 333 334 #endif 335