aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-eh.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-eh.c')
-rw-r--r--gcc/tree-eh.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 5bb07e49d28..7a028735d4e 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -2523,6 +2523,10 @@ operation_could_trap_p (enum tree_code op, bool fp_operation, bool honor_trapv,
bool honor_snans = fp_operation && flag_signaling_nans != 0;
bool handled;
+ /* This function cannot tell whether or not COND_EXPR and VEC_COND_EXPR could
+ trap, because that depends on the respective condition op. */
+ gcc_assert (op != COND_EXPR && op != VEC_COND_EXPR);
+
if (TREE_CODE_CLASS (op) != tcc_comparison
&& TREE_CODE_CLASS (op) != tcc_unary
&& TREE_CODE_CLASS (op) != tcc_binary)
@@ -2610,6 +2614,10 @@ tree_could_trap_p (tree expr)
if (!expr)
return false;
+ /* For COND_EXPR and VEC_COND_EXPR only the condition may trap. */
+ if (TREE_CODE (expr) == COND_EXPR || TREE_CODE (expr) == VEC_COND_EXPR)
+ expr = TREE_OPERAND (expr, 0);
+
code = TREE_CODE (expr);
t = TREE_TYPE (expr);
@@ -4040,15 +4048,14 @@ maybe_remove_unreachable_handlers (void)
if (cfun->eh == NULL)
return;
-
+
FOR_EACH_VEC_SAFE_ELT (cfun->eh->lp_array, i, lp)
- if (lp && lp->post_landing_pad)
+ if (lp
+ && (lp->post_landing_pad == NULL_TREE
+ || label_to_block (cfun, lp->post_landing_pad) == NULL))
{
- if (label_to_block (cfun, lp->post_landing_pad) == NULL)
- {
- remove_unreachable_handlers ();
- return;
- }
+ remove_unreachable_handlers ();
+ return;
}
}
@@ -4211,6 +4218,27 @@ unsplit_all_eh (void)
return changed;
}
+/* Wrapper around unsplit_all_eh that makes it usable everywhere. */
+
+void
+unsplit_eh_edges (void)
+{
+ bool changed;
+
+ /* unsplit_all_eh can die looking up unreachable landing pads. */
+ maybe_remove_unreachable_handlers ();
+
+ changed = unsplit_all_eh ();
+
+ /* If EH edges have been unsplit, delete unreachable forwarder blocks. */
+ if (changed)
+ {
+ free_dominance_info (CDI_DOMINATORS);
+ free_dominance_info (CDI_POST_DOMINATORS);
+ delete_unreachable_blocks ();
+ }
+}
+
/* A subroutine of cleanup_empty_eh. Redirect all EH edges incoming
to OLD_BB to NEW_BB; return true on success, false on failure.