aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-eh.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2017-03-17 12:48:56 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2017-03-17 12:48:56 +0000
commit12c4f7dcafc3fb469e995d283dccbb4a5945f11c (patch)
tree3a1c18ddfd849a4afa672dd26bb955d6f9e0cfa4 /gcc/tree-eh.c
parent5c7d37de415fe5345c005154ea69d0d9b5a8c8d6 (diff)
downloadgcc-12c4f7dcafc3fb469e995d283dccbb4a5945f11c.zip
gcc-12c4f7dcafc3fb469e995d283dccbb4a5945f11c.tar.gz
gcc-12c4f7dcafc3fb469e995d283dccbb4a5945f11c.tar.bz2
re PR c++/80075 (ICE: "statement marked for throw, but doesn’t" with -fnon-call-exceptions)
2017-03-17 Richard Biener <rguenther@suse.de> PR middle-end/80075 * tree-eh.c (stmt_could_throw_1_p): Only handle gimple assigns. Properly verify the LHS before the RHS possibly claims to be handled. (stmt_could_throw_p): Hande gimple conds fully here. Clobbers do not throw. * g++.dg/torture/pr80075.C: New testcase. From-SVN: r246223
Diffstat (limited to 'gcc/tree-eh.c')
-rw-r--r--gcc/tree-eh.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 0b785e9..fc016d7 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -2726,9 +2726,9 @@ tree_could_trap_p (tree expr)
an assignment or a conditional) may throw. */
static bool
-stmt_could_throw_1_p (gimple *stmt)
+stmt_could_throw_1_p (gassign *stmt)
{
- enum tree_code code = gimple_expr_code (stmt);
+ enum tree_code code = gimple_assign_rhs_code (stmt);
bool honor_nans = false;
bool honor_snans = false;
bool fp_operation = false;
@@ -2742,11 +2742,8 @@ stmt_could_throw_1_p (gimple *stmt)
|| TREE_CODE_CLASS (code) == tcc_binary
|| code == FMA_EXPR)
{
- if (is_gimple_assign (stmt)
- && TREE_CODE_CLASS (code) == tcc_comparison)
+ if (TREE_CODE_CLASS (code) == tcc_comparison)
t = TREE_TYPE (gimple_assign_rhs1 (stmt));
- else if (gimple_code (stmt) == GIMPLE_COND)
- t = TREE_TYPE (gimple_cond_lhs (stmt));
else
t = gimple_expr_type (stmt);
fp_operation = FLOAT_TYPE_P (t);
@@ -2759,17 +2756,21 @@ stmt_could_throw_1_p (gimple *stmt)
honor_trapv = true;
}
+ /* First check the LHS. */
+ if (tree_could_trap_p (gimple_assign_lhs (stmt)))
+ return true;
+
/* Check if the main expression may trap. */
- t = is_gimple_assign (stmt) ? gimple_assign_rhs2 (stmt) : NULL;
ret = operation_could_trap_helper_p (code, fp_operation, honor_trapv,
- honor_nans, honor_snans, t,
+ honor_nans, honor_snans,
+ gimple_assign_rhs2 (stmt),
&handled);
if (handled)
return ret;
/* If the expression does not trap, see if any of the individual operands may
trap. */
- for (i = 0; i < gimple_num_ops (stmt); i++)
+ for (i = 1; i < gimple_num_ops (stmt); i++)
if (tree_could_trap_p (gimple_op (stmt, i)))
return true;
@@ -2795,11 +2796,22 @@ stmt_could_throw_p (gimple *stmt)
case GIMPLE_CALL:
return !gimple_call_nothrow_p (as_a <gcall *> (stmt));
- case GIMPLE_ASSIGN:
case GIMPLE_COND:
- if (!cfun->can_throw_non_call_exceptions)
+ {
+ if (!cfun->can_throw_non_call_exceptions)
+ return false;
+ gcond *cond = as_a <gcond *> (stmt);
+ tree lhs = gimple_cond_lhs (cond);
+ return operation_could_trap_p (gimple_cond_code (cond),
+ FLOAT_TYPE_P (TREE_TYPE (lhs)),
+ false, NULL_TREE);
+ }
+
+ case GIMPLE_ASSIGN:
+ if (!cfun->can_throw_non_call_exceptions
+ || gimple_clobber_p (stmt))
return false;
- return stmt_could_throw_1_p (stmt);
+ return stmt_could_throw_1_p (as_a <gassign *> (stmt));
case GIMPLE_ASM:
if (!cfun->can_throw_non_call_exceptions)