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:
Richard Biener 2017-03-17 12:48:56 +00:00 committed by Richard Biener
parent 5c7d37de41
commit 12c4f7dcaf
4 changed files with 65 additions and 12 deletions

View File

@ -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>
* doc/invoke.texi (Option Options): Include -fipa-vrp in the list.

View File

@ -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>
PR target/71294

View File

@ -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;
}

View File

@ -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)