/* Implements exception handling.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
Contributed by Mike Stump <mrs@cygnus.com>.
This file is part of GCC.
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
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
/* An exception is an event that can be signaled from within a
for (prev_try = VEC_index (eh_region, cfun->eh->region_array, outer_region);
prev_try && prev_try->type != ERT_TRY;
prev_try = prev_try->outer)
- ;
+ if (prev_try->type == ERT_MUST_NOT_THROW
+ || (prev_try->type == ERT_ALLOWED_EXCEPTIONS
+ && !prev_try->u.allowed.type_list))
+ {
+ prev_try = NULL;
+ break;
+ }
/* Remap all of the internal catch and cleanup linkages. Since we
duplicate entire subtrees, all of the referenced regions will have
static int
t2r_eq (const void *pentry, const void *pdata)
{
- tree entry = (tree) pentry;
- tree data = (tree) pdata;
+ const_tree const entry = (const_tree) pentry;
+ const_tree const data = (const_tree) pdata;
return TREE_PURPOSE (entry) == data;
}
static hashval_t
t2r_hash (const void *pentry)
{
- tree entry = (tree) pentry;
+ const_tree const entry = (const_tree) pentry;
return TREE_HASH (TREE_PURPOSE (entry));
}
static int
ttypes_filter_eq (const void *pentry, const void *pdata)
{
- const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
- tree data = (tree) pdata;
+ const struct ttypes_filter *const entry
+ = (const struct ttypes_filter *) pentry;
+ const_tree const data = (const_tree) pdata;
return entry->t == data;
}
#ifdef DONT_USE_BUILTIN_SETJMP
{
- rtx x, note;
+ rtx x;
x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
TYPE_MODE (integer_type_node), 1,
plus_constant (XEXP (fc, 0),
for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin))
if (NOTE_P (fn_begin))
{
- if (NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
+ if (NOTE_KIND (fn_begin) == NOTE_INSN_FUNCTION_BEG)
break;
- else if (NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_BASIC_BLOCK)
+ else if (NOTE_INSN_BASIC_BLOCK_P (fn_begin))
fn_begin_outside_block = false;
}
/* We've totally changed the CFG. Start over. */
find_exception_handler_labels ();
break_superblocks ();
- if (USING_SJLJ_EXCEPTIONS)
+ if (USING_SJLJ_EXCEPTIONS
+ /* Kludge for Alpha/Tru64 (see alpha_gp_save_rtx). */
+ || single_succ_edge (ENTRY_BLOCK_PTR)->insns.r)
commit_edge_insertions ();
FOR_EACH_BB (bb)
{
static hashval_t
ehl_hash (const void *pentry)
{
- struct ehl_map_entry *entry = (struct ehl_map_entry *) pentry;
+ const struct ehl_map_entry *const entry
+ = (const struct ehl_map_entry *) pentry;
/* 2^32 * ((sqrt(5) - 1) / 2) */
const hashval_t scaled_golden_ratio = 0x9e3779b9;
static int
ehl_eq (const void *pentry, const void *pdata)
{
- struct ehl_map_entry *entry = (struct ehl_map_entry *) pentry;
- struct ehl_map_entry *data = (struct ehl_map_entry *) pdata;
+ const struct ehl_map_entry *const entry
+ = (const struct ehl_map_entry *) pentry;
+ const struct ehl_map_entry *const data
+ = (const struct ehl_map_entry *) pdata;
return entry->label == data->label;
}
}
bool
-can_throw_internal (rtx insn)
+can_throw_internal (const_rtx insn)
{
rtx note;
}
bool
-can_throw_external (rtx insn)
+can_throw_external (const_rtx insn)
{
rtx note;
{
rtx insn;
- if (!targetm.binds_local_p (current_function_decl))
+ /* If we don't know that this implementation of the function will
+ actually be used, then we must not set TREE_NOTHROW, since
+ callers must not assume that this function does not throw. */
+ if (DECL_REPLACEABLE_P (current_function_decl))
return 0;
TREE_NOTHROW (current_function_decl) = 1;
{
/* Set this so all the registers get saved in our frame; we need to be
able to copy the saved values for any registers from frames we unwind. */
- current_function_has_nonlocal_label = 1;
+ current_function_saves_all_registers = 1;
#ifdef SETUP_FRAME_ADDRESSES
SETUP_FRAME_ADDRESSES ();
}
rtx
-expand_builtin_eh_return_data_regno (tree arglist)
+expand_builtin_eh_return_data_regno (tree exp)
{
- tree which = TREE_VALUE (arglist);
+ tree which = CALL_EXPR_ARG (exp, 0);
unsigned HOST_WIDE_INT iwhich;
if (TREE_CODE (which) != INTEGER_CST)
rtx
expand_builtin_extract_return_addr (tree addr_tree)
{
- rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
+ rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
if (GET_MODE (addr) != Pmode
&& GET_MODE (addr) != VOIDmode)
rtx
expand_builtin_frob_return_addr (tree addr_tree)
{
- rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, 0);
+ rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, EXPAND_NORMAL);
addr = convert_memory_address (Pmode, addr);
rtx tmp;
#ifdef EH_RETURN_STACKADJ_RTX
- tmp = expand_expr (stackadj_tree, cfun->eh->ehr_stackadj, VOIDmode, 0);
+ tmp = expand_expr (stackadj_tree, cfun->eh->ehr_stackadj,
+ VOIDmode, EXPAND_NORMAL);
tmp = convert_memory_address (Pmode, tmp);
if (!cfun->eh->ehr_stackadj)
cfun->eh->ehr_stackadj = copy_to_reg (tmp);
emit_move_insn (cfun->eh->ehr_stackadj, tmp);
#endif
- tmp = expand_expr (handler_tree, cfun->eh->ehr_handler, VOIDmode, 0);
+ tmp = expand_expr (handler_tree, cfun->eh->ehr_handler,
+ VOIDmode, EXPAND_NORMAL);
tmp = convert_memory_address (Pmode, tmp);
if (!cfun->eh->ehr_handler)
cfun->eh->ehr_handler = copy_to_reg (tmp);
rtx
expand_builtin_extend_pointer (tree addr_tree)
{
- rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, 0);
+ rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, EXPAND_NORMAL);
int extend;
#ifdef POINTERS_EXTEND_UNSIGNED
value = const0_rtx;
else
{
- struct cgraph_varpool_node *node;
+ struct varpool_node *node;
type = lookup_type_for_runtime (type);
value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
type = TREE_OPERAND (type, 0);
if (TREE_CODE (type) == VAR_DECL)
{
- node = cgraph_varpool_node (type);
+ node = varpool_node (type);
if (node)
- cgraph_varpool_mark_needed_node (node);
+ varpool_mark_needed_node (node);
public = TREE_PUBLIC (type);
}
}
int have_tt_data;
int tt_format_size = 0;
- if (eh_personality_libfunc)
- assemble_external_libcall (eh_personality_libfunc);
-
/* Not all functions need anything. */
if (! cfun->uses_eh_lsda)
return;
+ if (eh_personality_libfunc)
+ assemble_external_libcall (eh_personality_libfunc);
+
#ifdef TARGET_UNWIND_INFO
/* TODO: Move this into target file. */
fputs ("\t.personality\t", asm_out_file);