From: Richard Biener Date: Fri, 17 Mar 2017 12:48:56 +0000 (+0000) Subject: re PR c++/80075 (ICE: "statement marked for throw, but doesn’t" with -fnon-call-excep... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=12c4f7dcafc3fb469e995d283dccbb4a5945f11c;p=gcc.git re PR c++/80075 (ICE: "statement marked for throw, but doesn’t" with -fnon-call-exceptions) 2017-03-17 Richard Biener 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 76da3f1090e..9af58154dd2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2017-03-17 Richard Biener + + 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. + 2017-03-17 Martin Jambor * doc/invoke.texi (Option Options): Include -fipa-vrp in the list. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 72c74df18d2..144030e8c0f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-03-17 Richard Biener + + PR middle-end/80075 + * g++.dg/torture/pr80075.C: New testcase. + 2017-03-16 Michael Meissner PR target/71294 diff --git a/gcc/testsuite/g++.dg/torture/pr80075.C b/gcc/testsuite/g++.dg/torture/pr80075.C new file mode 100644 index 00000000000..5bc802027c0 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr80075.C @@ -0,0 +1,27 @@ +// { dg-do compile } +// { dg-additional-options "-fnon-call-exceptions" } + +struct s { + int i; +}; + +extern int use_memcpy; +extern void my_memcpy(void*, void*, int); + +int +f (struct s* p) +{ + struct s a; + + try + { + a = (struct s){}; + if (!use_memcpy) + *p = a; + else + my_memcpy (p, &a, sizeof (struct s)); + } catch (...) { + return 0; + } + return 1; +} diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 0b785e9b314..fc016d795b7 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 (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 (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 (stmt)); case GIMPLE_ASM: if (!cfun->can_throw_non_call_exceptions)