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
This commit is contained in:
parent
5c7d37de41
commit
12c4f7dcaf
|
@ -1,3 +1,12 @@
|
||||||
|
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.
|
||||||
|
|
||||||
2017-03-17 Martin Jambor <mjambor@suse.cz>
|
2017-03-17 Martin Jambor <mjambor@suse.cz>
|
||||||
|
|
||||||
* doc/invoke.texi (Option Options): Include -fipa-vrp in the list.
|
* doc/invoke.texi (Option Options): Include -fipa-vrp in the list.
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2017-03-17 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
PR middle-end/80075
|
||||||
|
* g++.dg/torture/pr80075.C: New testcase.
|
||||||
|
|
||||||
2017-03-16 Michael Meissner <meissner@linux.vnet.ibm.com>
|
2017-03-16 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||||
|
|
||||||
PR target/71294
|
PR target/71294
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -2726,9 +2726,9 @@ tree_could_trap_p (tree expr)
|
||||||
an assignment or a conditional) may throw. */
|
an assignment or a conditional) may throw. */
|
||||||
|
|
||||||
static bool
|
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_nans = false;
|
||||||
bool honor_snans = false;
|
bool honor_snans = false;
|
||||||
bool fp_operation = false;
|
bool fp_operation = false;
|
||||||
|
@ -2742,11 +2742,8 @@ stmt_could_throw_1_p (gimple *stmt)
|
||||||
|| TREE_CODE_CLASS (code) == tcc_binary
|
|| TREE_CODE_CLASS (code) == tcc_binary
|
||||||
|| code == FMA_EXPR)
|
|| code == FMA_EXPR)
|
||||||
{
|
{
|
||||||
if (is_gimple_assign (stmt)
|
if (TREE_CODE_CLASS (code) == tcc_comparison)
|
||||||
&& TREE_CODE_CLASS (code) == tcc_comparison)
|
|
||||||
t = TREE_TYPE (gimple_assign_rhs1 (stmt));
|
t = TREE_TYPE (gimple_assign_rhs1 (stmt));
|
||||||
else if (gimple_code (stmt) == GIMPLE_COND)
|
|
||||||
t = TREE_TYPE (gimple_cond_lhs (stmt));
|
|
||||||
else
|
else
|
||||||
t = gimple_expr_type (stmt);
|
t = gimple_expr_type (stmt);
|
||||||
fp_operation = FLOAT_TYPE_P (t);
|
fp_operation = FLOAT_TYPE_P (t);
|
||||||
|
@ -2759,17 +2756,21 @@ stmt_could_throw_1_p (gimple *stmt)
|
||||||
honor_trapv = true;
|
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. */
|
/* 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,
|
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);
|
&handled);
|
||||||
if (handled)
|
if (handled)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* If the expression does not trap, see if any of the individual operands may
|
/* If the expression does not trap, see if any of the individual operands may
|
||||||
trap. */
|
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)))
|
if (tree_could_trap_p (gimple_op (stmt, i)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -2795,11 +2796,22 @@ stmt_could_throw_p (gimple *stmt)
|
||||||
case GIMPLE_CALL:
|
case GIMPLE_CALL:
|
||||||
return !gimple_call_nothrow_p (as_a <gcall *> (stmt));
|
return !gimple_call_nothrow_p (as_a <gcall *> (stmt));
|
||||||
|
|
||||||
case GIMPLE_ASSIGN:
|
|
||||||
case GIMPLE_COND:
|
case GIMPLE_COND:
|
||||||
|
{
|
||||||
if (!cfun->can_throw_non_call_exceptions)
|
if (!cfun->can_throw_non_call_exceptions)
|
||||||
return false;
|
return false;
|
||||||
return stmt_could_throw_1_p (stmt);
|
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 (as_a <gassign *> (stmt));
|
||||||
|
|
||||||
case GIMPLE_ASM:
|
case GIMPLE_ASM:
|
||||||
if (!cfun->can_throw_non_call_exceptions)
|
if (!cfun->can_throw_non_call_exceptions)
|
||||||
|
|
Loading…
Reference in New Issue