diff options
Diffstat (limited to 'gcc-4.8/gcc/tree-eh.c')
-rw-r--r-- | gcc-4.8/gcc/tree-eh.c | 48 |
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 (); |