/* Exception handling semantics and decomposition for trees.
- Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
#include "langhooks.h"
#include "ggc.h"
-/* In some circumstances we have to save EH data around a nested
- exception. The EXC_PTR_EXPR and FILTER_EXPR values are saved
- into these _DECL nodes.
-
- We lazily create this pair of _DECL nodes once per function rather
- than creating a new pair of _DECLs each time we need to save the
- EXEC_PTR and FILTER. This can save us literally thousands of _DECL
- nodes when we have many inline destructors with an embedded try block.
-
- This is safe as we know the lifetime of the values in these _DECL nodes.
- Their lifetimes also ensure that globbing these uses into a single
- pair of _DECL nodes requires no additional PHI_NODEs or SSA_NAMEs when
- compared to having a pair of _DECL nodes per inline destructor with
- an embedded try block. */
-static tree save_eptr, save_filt;
\f
/* Nonzero if we are using EH to handle cleanups. */
static int using_eh_for_cleanups_p = 0;
static void
replace_goto_queue (struct leh_tf_state *tf)
{
+ if (tf->goto_queue_active == 0)
+ return;
replace_goto_queue_stmt_list (*tf->top_p, tf);
}
alternative considered below. For the nonce, we always choose the first
option.
- THIS_STATE may be null if if this is a try-cleanup, not a try-finally. */
+ THIS_STATE may be null if this is a try-cleanup, not a try-finally. */
static void
honor_protect_cleanup_actions (struct leh_state *outer_state,
we never fallthru from this copy of the finally block. */
if (finally_may_fallthru)
{
- /* If we have not created _DECLs for saving the EXC_PTR
- and FILTER_EXPR, create them now. */
- if (!save_eptr)
- {
- save_eptr = create_tmp_var (ptr_type_node, "save_eptr");
- save_filt = create_tmp_var (integer_type_node, "save_filt");
- }
+ tree save_eptr, save_filt;
+
+ save_eptr = create_tmp_var (ptr_type_node, "save_eptr");
+ save_filt = create_tmp_var (integer_type_node, "save_filt");
i = tsi_start (finally);
x = build (EXC_PTR_EXPR, ptr_type_node);
htab_delete (finally_tree);
collect_eh_region_array ();
-
- /* Wipe the DECLs we use for saving the EXC_PTR and FILTER_EXPR
- to ensure we create new ones for the next function. */
- save_eptr = NULL;
- save_filt = NULL;
}
struct tree_opt_pass pass_lower_eh =
bool honor_snans = false;
bool fp_operation = false;
bool honor_trapv = false;
- tree t, base, idx;
+ tree t, base;
if (TREE_CODE_CLASS (code) == tcc_comparison
|| TREE_CODE_CLASS (code) == tcc_unary
case ARRAY_REF:
base = TREE_OPERAND (expr, 0);
- idx = TREE_OPERAND (expr, 1);
if (tree_could_trap_p (base))
return true;
return true;
return false;
+ case CALL_EXPR:
+ t = get_callee_fndecl (expr);
+ /* Assume that calls to weak functions may trap. */
+ if (!t || !DECL_P (t) || DECL_WEAK (t))
+ return true;
+ return false;
+
default:
/* Any floating arithmetic may trap. */
if (fp_operation && flag_trapping_math)