except.h 12 KB
Newer Older
Mike Stump committed
1
/* Exception Handling interface routines.
Jakub Jelinek committed
2
   Copyright (C) 1996-2015 Free Software Foundation, Inc.
Mike Stump committed
3 4
   Contributed by Mike Stump <mrs@cygnus.com>.

5
This file is part of GCC.
Mike Stump committed
6

7 8
GCC is free software; you can redistribute it and/or modify it under
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.
Mike Stump committed
11

12 13 14 15
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.
Mike Stump committed
16 17

You should have received a copy of the GNU General Public License
18 19
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
Mike Stump committed
20

21 22 23 24
/* No include guards here, but define an include file marker anyway, so
   that the compiler can keep track of where this file is included.  This
   is e.g. used to avoid including this file in front-end specific files.  */
#ifndef GCC_EXCEPT_H
25
#define GCC_EXCEPT_H
26

27

28
struct function;
29
struct eh_region_d;
30

31 32 33
/* The type of an exception region.  */
enum eh_region_type
{
34 35 36 37 38
  /* CLEANUP regions implement e.g. destructors run when exiting a block.
     They can be generated from both GIMPLE_TRY_FINALLY and GIMPLE_TRY_CATCH
     nodes.  It is expected by the runtime that cleanup regions will *not*
     resume normal program flow, but will continue propagation of the
     exception.  */
39
  ERT_CLEANUP,
40 41 42

  /* TRY regions implement catching an exception.  The list of types associated
     with the attached catch handlers is examined in order by the runtime and
Joseph Myers committed
43
     control is transferred to the appropriate handler.  Note that a NULL type
44 45
     list is a catch-all handler, and that it will catch *all* exceptions
     including those originating from a different language.  */
46
  ERT_TRY,
47 48 49 50 51 52

  /* ALLOWED_EXCEPTIONS regions implement exception filtering, e.g. the
     throw(type-list) specification that can be added to C++ functions.
     The runtime examines the thrown exception vs the type list, and if
     the exception does not match, transfers control to the handler.  The
     normal handler for C++ calls __cxa_call_unexpected.  */
53
  ERT_ALLOWED_EXCEPTIONS,
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76

  /* MUST_NOT_THROW regions prevent all exceptions from propagating.  This
     region type is used in C++ to surround destructors being run inside a
     CLEANUP region.  This differs from an ALLOWED_EXCEPTIONS region with
     an empty type list in that the runtime is prepared to terminate the
     program directly.  We only generate code for MUST_NOT_THROW regions
     along control paths that are already handling an exception within the
     current function.  */
  ERT_MUST_NOT_THROW
};


/* A landing pad for a given exception region.  Any transfer of control
   from the EH runtime to the function happens at a landing pad.  */

struct GTY(()) eh_landing_pad_d
{
  /* The linked list of all landing pads associated with the region.  */
  struct eh_landing_pad_d *next_lp;

  /* The region with which this landing pad is associated.  */
  struct eh_region_d *region;

Joseph Myers committed
77
  /* At the gimple level, the location to which control will be transferred
78 79 80 81 82 83 84 85 86
     for this landing pad.  There can be both EH and normal edges into the
     block containing the post-landing-pad label.  */
  tree post_landing_pad;

  /* At the rtl level, the location to which the runtime will transfer
     control.  This differs from the post-landing-pad in that the target's
     EXCEPTION_RECEIVER pattern will be expanded here, as well as other
     bookkeeping specific to exceptions.  There must not be normal edges
     into the block containing the landing-pad label.  */
87
  rtx_code_label *landing_pad;
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

  /* The index of this landing pad within fun->eh->lp_array.  */
  int index;
};

/* A catch handler associated with an ERT_TRY region.  */

struct GTY(()) eh_catch_d
{
  /* The double-linked list of all catch handlers for the region.  */
  struct eh_catch_d *next_catch;
  struct eh_catch_d *prev_catch;

  /* A TREE_LIST of runtime type objects that this catch handler
     will catch, or NULL if all exceptions are caught.  */
  tree type_list;

  /* A TREE_LIST of INTEGER_CSTs that correspond to the type_list entries,
     having been mapped by assign_filter_values.  These integers are to be
     compared against the __builtin_eh_filter value.  */
  tree filter_list;

  /* The code that should be executed if this catch handler matches the
     thrown exception.  This label is only maintained until
     pass_lower_eh_dispatch, at which point it is cleared.  */
  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 125
  struct eh_region_d *inner;
  struct eh_region_d *next_peer;
126

127 128
  /* The index of this region within fun->eh->region_array.  */
  int index;
129 130

  /* Each region does exactly one thing.  */
131
  enum eh_region_type type;
132 133 134 135

  /* Holds the action to perform based on the preceding type.  */
  union eh_region_u {
    struct eh_region_u_try {
136 137 138
      /* The double-linked list of all catch handlers for this region.  */
      struct eh_catch_d *first_catch;
      struct eh_catch_d *last_catch;
139 140 141
    } GTY ((tag ("ERT_TRY"))) eh_try;

    struct eh_region_u_allowed {
142
      /* A TREE_LIST of runtime type objects allowed to pass.  */
143
      tree type_list;
144 145 146 147 148 149 150 151
      /* The code that should be executed if the thrown exception does
	 not match the type list.  This label is only maintained until
	 pass_lower_eh_dispatch, at which point it is cleared.  */
      tree label;
      /* The integer that will be passed by the runtime to signal that
	 we should execute the code at LABEL.  This integer is assigned
	 by assign_filter_values and is to be compared against the
	 __builtin_eh_filter value.  */
152 153 154
      int filter;
    } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;

155 156 157 158 159 160
    struct eh_region_u_must_not_throw {
      /* A function decl to be invoked if this region is actually reachable
	 from within the function, rather than implementable from the runtime.
	 The normal way for this to happen is for there to be a CLEANUP region
	 contained within this MUST_NOT_THROW region.  Note that if the
	 runtime handles the MUST_NOT_THROW region, we have no control over
H.J. Lu committed
161
	 what termination function is called; it will be decided by the
162 163 164 165 166
	 personality function in effect for this CIE.  */
      tree failure_decl;
      /* The location assigned to the call of FAILURE_DECL, if expanded.  */
      location_t failure_loc;
    } GTY ((tag ("ERT_MUST_NOT_THROW"))) must_not_throw;
167 168
  } GTY ((desc ("%0.type"))) u;

169 170
  /* The list of landing pads associated with this region.  */
  struct eh_landing_pad_d *landing_pads;
171

172 173 174 175
  /* EXC_PTR and FILTER values copied from the runtime for this region.
     Each region gets its own psuedos so that if there are nested exceptions
     we do not overwrite the values of the first exception.  */
  rtx exc_ptr_reg, filter_reg;
176 177 178 179

  /* True if this region should use __cxa_end_cleanup instead
     of _Unwind_Resume.  */
  bool use_cxa_end_cleanup;
180 181
};

182 183
typedef struct eh_landing_pad_d *eh_landing_pad;
typedef struct eh_catch_d *eh_catch;
184
typedef struct eh_region_d *eh_region;
185

186

187 188 189 190


/* The exception status for each function.  */

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 203

  /* At the gimple level, a mapping from gimple statement to landing pad
     or must-not-throw region.  See record_stmt_eh_region.  */
204
  hash_map<gimple, int> *GTY(()) throw_stmt_table;
205 206 207

  /* All of the runtime type data used by the function.  These objects
     are emitted to the lang-specific-data-area for the function.  */
208
  vec<tree, va_gc> *ttype_data;
209 210 211 212 213 214

  /* The table of all action chains.  These encode the eh_region tree in
     a compact form for use by the runtime, and is also emitted to the
     lang-specific-data-area.  Note that the ARM EABI uses a different
     format for the encoding than all other ports.  */
  union eh_status_u {
215 216
    vec<tree, va_gc> *GTY((tag ("1"))) arm_eabi;
    vec<uchar, va_gc> *GTY((tag ("0"))) other;
217
  } GTY ((desc ("targetm.arm_eabi_unwinder"))) ehspec_data;
218
};
Richard Kenner committed
219

220

221 222
/* Invokes CALLBACK for every exception handler label.  Only used by old
   loop hackery; should not be used by new code.  */
223
extern void for_each_eh_label (void (*) (rtx));
Mike Stump committed
224

225
extern void init_eh_for_function (void);
Richard Kenner committed
226

227 228
extern void remove_eh_landing_pad (eh_landing_pad);
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 (const char *);
Teemu Torma committed
233

234 235 236
extern rtx expand_builtin_eh_pointer (tree);
extern rtx expand_builtin_eh_filter (tree);
extern rtx expand_builtin_eh_copy_values (tree);
237 238 239 240 241 242 243 244
extern void expand_builtin_unwind_init (void);
extern rtx expand_builtin_eh_return_data_regno (tree);
extern rtx expand_builtin_extract_return_addr (tree);
extern void expand_builtin_init_dwarf_reg_sizes (tree);
extern rtx expand_builtin_frob_return_addr (tree);
extern rtx expand_builtin_dwarf_sp_column (void);
extern void expand_builtin_eh_return (tree, tree);
extern void expand_eh_return (void);
245
extern rtx expand_builtin_extend_pointer (tree);
246
extern void expand_dw2_landing_pad_for_region (eh_region);
247

248
typedef tree (*duplicate_eh_regions_map) (tree, void *);
249
extern hash_map<void *, void *> *duplicate_eh_regions
250
  (struct function *, eh_region, int, duplicate_eh_regions_map, void *);
251

252
extern void sjlj_emit_function_exit_after (rtx_insn *);
253
extern void update_sjlj_context (void);
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271

extern eh_region gen_eh_region_cleanup (eh_region);
extern eh_region gen_eh_region_try (eh_region);
extern eh_region gen_eh_region_allowed (eh_region, tree);
extern eh_region gen_eh_region_must_not_throw (eh_region);

extern eh_catch gen_eh_region_catch (eh_region, tree);
extern eh_landing_pad gen_eh_landing_pad (eh_region);

extern eh_region get_eh_region_from_number_fn (struct function *, int);
extern eh_region get_eh_region_from_number (int);
extern eh_landing_pad get_eh_landing_pad_from_number_fn (struct function*,int);
extern eh_landing_pad get_eh_landing_pad_from_number (int);
extern eh_region get_eh_region_from_lp_number_fn (struct function *, int);
extern eh_region get_eh_region_from_lp_number (int);

extern eh_region eh_region_outermost (struct function *, eh_region, eh_region);

272 273
extern void make_reg_eh_region_note (rtx_insn *insn, int ecf_flags, int lp_nr);
extern void make_reg_eh_region_note_nothrow_nononlocal (rtx_insn *);
274

275 276
extern void verify_eh_tree (struct function *);
extern void dump_eh_tree (FILE *, struct function *);
277 278 279
void debug_eh_tree (struct function *);
extern void add_type_for_runtime (tree);
extern tree lookup_type_for_runtime (tree);
280 281 282 283
extern void assign_filter_values (void);

extern eh_region get_eh_region_from_rtx (const_rtx);
extern eh_landing_pad get_eh_landing_pad_from_rtx (const_rtx);
284

285 286
extern void finish_eh_generation (void);

287
struct GTY(()) throw_stmt_node {
288
  gimple stmt;
289
  int lp_nr;
290 291
};

292 293
extern hash_map<gimple, int> *get_eh_throw_stmt_table (struct function *);
extern void set_eh_throw_stmt_table (function *, hash_map<gimple, int> *);
294 295 296 297 298 299 300 301 302

enum eh_personality_kind {
  eh_personality_none,
  eh_personality_any,
  eh_personality_lang
};

extern enum eh_personality_kind
function_needs_eh_personality (struct function *);
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333

/* Pre-order iteration within the eh_region tree.  */

static inline eh_region
ehr_next (eh_region r, eh_region start)
{
  if (r->inner)
    r = r->inner;
  else if (r->next_peer && r != start)
    r = r->next_peer;
  else
    {
      do
	{
	  r = r->outer;
	  if (r == start)
	    return NULL;
	}
      while (r->next_peer == NULL);
      r = r->next_peer;
    }
  return r;
}

#define FOR_ALL_EH_REGION_AT(R, START) \
  for ((R) = (START); (R) != NULL; (R) = ehr_next (R, START))

#define FOR_ALL_EH_REGION_FN(R, FN) \
  for ((R) = (FN)->eh->region_tree; (R) != NULL; (R) = ehr_next (R, NULL))

#define FOR_ALL_EH_REGION(R) FOR_ALL_EH_REGION_FN (R, cfun)
334 335

#endif