diff options
author | Richard Biener <rguenther@suse.de> | 2017-03-17 12:48:56 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2017-03-17 12:48:56 +0000 |
commit | 12c4f7dcafc3fb469e995d283dccbb4a5945f11c (patch) | |
tree | 3a1c18ddfd849a4afa672dd26bb955d6f9e0cfa4 /gcc/tree-eh.c | |
parent | 5c7d37de415fe5345c005154ea69d0d9b5a8c8d6 (diff) | |
download | gcc-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.c | 36 |
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) |