/* Implements exception handling.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Contributed by Mike Stump <mrs@cygnus.com>.
a given statement does throw. During this lowering process,
we create an EH_LANDING_PAD node for each EH_REGION that has
some code within the function that needs to be executed if a
- throw does happen. We also create RESX statements that are
+ throw does happen. We also create RESX statements that are
used to transfer control from an inner EH_REGION to an outer
EH_REGION. We also create EH_DISPATCH statements as placeholders
for a runtime type comparison that should be made in order to
handler for the exception must be within a function somewhere
up the call chain, so we call back into the exception runtime
(__builtin_unwind_resume).
-
+
During pass_expand (cfgexpand.c), we generate REG_EH_REGION notes
that create an rtl to eh_region mapping that corresponds to the
gimple to eh_region mapping that had been recorded in the
frame are emitted at this time.
During pass_convert_to_eh_region_ranges (except.c), we transform
- the REG_EH_REGION notes attached to individual insns into
+ the REG_EH_REGION notes attached to individual insns into
non-overlapping ranges of insns bounded by NOTE_INSN_EH_REGION_BEG
and NOTE_INSN_EH_REGION_END. Each insn within such ranges has the
same associated action within the exception region tree, meaning
to the given failure handler. */
tree (*lang_protect_cleanup_actions) (void);
-/* Return true if type A catches type B. */
-int (*lang_eh_type_covers) (tree a, tree b);
-
static GTY(()) int call_site_base;
static GTY ((param_is (union tree_node)))
htab_t type_to_runtime_map;
new_eh->index = VEC_length (eh_region, cfun->eh->region_array);
VEC_safe_push (eh_region, gc, cfun->eh->region_array, new_eh);
+ /* Copy the language's notion of whether to use __cxa_end_cleanup. */
+ if (targetm.arm_eabi_unwinder && lang_hooks.eh_use_cxa_end_cleanup)
+ new_eh->use_cxa_end_cleanup = true;
+
return new_eh;
}
case ERT_ALLOWED_EXCEPTIONS:
new_r->u.allowed.type_list = old_r->u.allowed.type_list;
- new_r->u.allowed.label
- = data->label_map (old_r->u.allowed.label, data->label_map_data);
+ if (old_r->u.allowed.label)
+ new_r->u.allowed.label
+ = data->label_map (old_r->u.allowed.label, data->label_map_data);
+ else
+ new_r->u.allowed.label = NULL_TREE;
break;
case ERT_MUST_NOT_THROW:
EH_LANDING_PAD_NR (new_lp->post_landing_pad) = new_lp->index;
}
+ /* Make sure to preserve the original use of __cxa_end_cleanup. */
+ new_r->use_cxa_end_cleanup = old_r->use_cxa_end_cleanup;
+
for (old_r = old_r->inner; old_r ; old_r = old_r->next_peer)
duplicate_eh_regions_1 (data, old_r, new_r);
}
data.eh_map = pointer_map_create ();
outer_region = get_eh_region_from_lp_number (outer_lp);
-
+
/* Copy all the regions in the subtree. */
if (copy_region)
duplicate_eh_regions_1 (&data, copy_region, outer_region);
lp->landing_pad = gen_label_rtx ();
emit_label (lp->landing_pad);
+ LABEL_PRESERVE_P (lp->landing_pad) = 1;
#ifdef HAVE_exception_receiver
if (HAVE_exception_receiver)
#ifdef DONT_USE_BUILTIN_SETJMP
{
- rtx x;
+ rtx x, last;
x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
TYPE_MODE (integer_type_node), 1,
plus_constant (XEXP (fc, 0),
emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
TYPE_MODE (integer_type_node), 0, dispatch_label);
- add_reg_br_prob_note (get_insns (), REG_BR_PROB_BASE/100);
+ last = get_last_insn ();
+ if (JUMP_P (last) && any_condjump_p (last))
+ {
+ gcc_assert (!find_reg_note (last, REG_BR_PROB, 0));
+ add_reg_note (last, REG_BR_PROB, GEN_INT (REG_BR_PROB_BASE / 100));
+ }
}
#else
expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs),
{
{
RTL_PASS,
- "eh", /* name */
+ "rtl eh", /* name */
gate_handle_eh, /* gate */
rest_of_handle_eh, /* execute */
NULL, /* sub */
for (pp = &lp->region->landing_pads; *pp != lp; pp = &(*pp)->next_lp)
continue;
*pp = lp->next_lp;
-
+
if (lp->post_landing_pad)
EH_LANDING_PAD_NR (lp->post_landing_pad) = 0;
VEC_replace (eh_landing_pad, cfun->eh->lp_array, lp->index, NULL);
}
\f
/* Create the REG_EH_REGION note for INSN, given its ECF_FLAGS for a
- call insn.
+ call insn.
At the gimple level, we use LP_NR
> 0 : The statement transfers to landing pad LP_NR
\f
/* Set TREE_NOTHROW and crtl->all_throwers_are_sibcalls. */
-unsigned int
+static unsigned int
set_nothrow_function_flags (void)
{
rtx insn;
struct cgraph_edge *e;
for (e = node->callers; e; e = e->next_caller)
e->can_throw_external = false;
- TREE_NOTHROW (current_function_decl) = 1;
+ cgraph_set_nothrow_flag (node, true);
if (dump_file)
fprintf (dump_file, "Marking function nothrow: %s\n\n",
{
struct varpool_node *node;
- type = lookup_type_for_runtime (type);
+ /* FIXME lto. pass_ipa_free_lang_data changes all types to
+ runtime types so TYPE should already be a runtime type
+ reference. When pass_ipa_free_lang data is made a default
+ pass, we can then remove the call to lookup_type_for_runtime
+ below. */
+ if (TYPE_P (type))
+ type = lookup_type_for_runtime (type);
+
value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
/* Let cgraph know that the rtti decl is used. Not all of the