aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8/gcc/tree-eh.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.8/gcc/tree-eh.c')
-rw-r--r--gcc-4.8/gcc/tree-eh.c48
1 files changed, 35 insertions, 13 deletions
diff --git a/gcc-4.8/gcc/tree-eh.c b/gcc-4.8/gcc/tree-eh.c
index 973782ba5..f139d38c4 100644
--- a/gcc-4.8/gcc/tree-eh.c
+++ b/gcc-4.8/gcc/tree-eh.c
@@ -1357,9 +1357,6 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
x = gimple_seq_last_stmt (finally);
finally_loc = x ? gimple_location (x) : tf_loc;
- /* Lower the finally block itself. */
- lower_eh_constructs_1 (state, &finally);
-
/* Prepare for switch statement generation. */
nlabels = tf->dest_array.length ();
return_index = nlabels;
@@ -1445,6 +1442,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
x = gimple_build_label (finally_label);
gimple_seq_add_stmt (&tf->top_p_seq, x);
+ lower_eh_constructs_1 (state, &finally);
gimple_seq_add_seq (&tf->top_p_seq, finally);
/* Redirect each incoming goto edge. */
@@ -2502,12 +2500,6 @@ tree_could_trap_p (tree expr)
restart:
switch (code)
{
- case TARGET_MEM_REF:
- if (TREE_CODE (TMR_BASE (expr)) == ADDR_EXPR
- && !TMR_INDEX (expr) && !TMR_INDEX2 (expr))
- return false;
- return !TREE_THIS_NOTRAP (expr);
-
case COMPONENT_REF:
case REALPART_EXPR:
case IMAGPART_EXPR:
@@ -2534,10 +2526,36 @@ tree_could_trap_p (tree expr)
return false;
return !in_array_bounds_p (expr);
+ case TARGET_MEM_REF:
case MEM_REF:
+ if (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR
+ && tree_could_trap_p (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)))
+ return true;
+ if (TREE_THIS_NOTRAP (expr))
+ return false;
+ /* We cannot prove that the access is in-bounds when we have
+ variable-index TARGET_MEM_REFs. */
+ if (code == TARGET_MEM_REF
+ && (TMR_INDEX (expr) || TMR_INDEX2 (expr)))
+ return true;
if (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
+ {
+ tree base = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
+ double_int off = mem_ref_offset (expr);
+ if (off.is_negative ())
+ return true;
+ if (TREE_CODE (base) == STRING_CST)
+ return double_int::from_uhwi (TREE_STRING_LENGTH (base)).ule (off);
+ else if (DECL_SIZE_UNIT (base) == NULL_TREE
+ || TREE_CODE (DECL_SIZE_UNIT (base)) != INTEGER_CST
+ || tree_to_double_int (DECL_SIZE_UNIT (base)).ule (off))
+ return true;
+ /* Now we are sure the first byte of the access is inside
+ the object. */
return false;
- /* Fallthru. */
+ }
+ return true;
+
case INDIRECT_REF:
return !TREE_THIS_NOTRAP (expr);
@@ -4166,8 +4184,11 @@ cleanup_empty_eh (eh_landing_pad lp)
/* If the block is totally empty, look for more unsplitting cases. */
if (gsi_end_p (gsi))
{
- /* For the degenerate case of an infinite loop bail out. */
- if (infinite_empty_loop_p (e_out))
+ /* For the degenerate case of an infinite loop bail out.
+ If bb has no successors and is totally empty, which can happen e.g.
+ because of incorrect noreturn attribute, bail out too. */
+ if (e_out == NULL
+ || infinite_empty_loop_p (e_out))
return ret;
return ret | cleanup_empty_eh_unsplit (bb, e_out, lp);
@@ -4304,10 +4325,11 @@ execute_cleanup_eh_1 (void)
remove_unreachable_handlers ();
/* Watch out for the region tree vanishing due to all unreachable. */
- if (cfun->eh->region_tree && optimize)
+ if (cfun->eh->region_tree)
{
bool changed = false;
+ if (optimize)
changed |= unsplit_all_eh ();
changed |= cleanup_all_empty_eh ();