This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix stmt_could_throw_1_p for constructor RHS
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 17 Mar 2017 13:18:00 +0100 (CET)
- Subject: [PATCH] Fix stmt_could_throw_1_p for constructor RHS
- Authentication-results: sourceware.org; auth=none
Ever since operation_could_trap_helper_p claimed that CONSTRUCTOR
(or COMPLEX_EXPR) cannot throw stmt_could_throw_1_p ignored whether
the LHS of an assignment possibly could. The following fixes this
by refactoring the code a bit and handling the LHS before the
RHS.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
Richard.
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.
Index: gcc/tree-eh.c
===================================================================
*** gcc/tree-eh.c (revision 246216)
--- gcc/tree-eh.c (working copy)
*************** tree_could_trap_p (tree expr)
*** 2726,2734 ****
an assignment or a conditional) may throw. */
static bool
! stmt_could_throw_1_p (gimple *stmt)
{
! enum tree_code code = gimple_expr_code (stmt);
bool honor_nans = false;
bool honor_snans = false;
bool fp_operation = false;
--- 2726,2734 ----
an assignment or a conditional) may throw. */
static bool
! stmt_could_throw_1_p (gassign *stmt)
{
! enum tree_code code = gimple_assign_rhs_code (stmt);
bool honor_nans = false;
bool honor_snans = false;
bool fp_operation = false;
*************** stmt_could_throw_1_p (gimple *stmt)
*** 2742,2752 ****
|| TREE_CODE_CLASS (code) == tcc_binary
|| code == FMA_EXPR)
{
! if (is_gimple_assign (stmt)
! && 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);
--- 2742,2749 ----
|| TREE_CODE_CLASS (code) == tcc_binary
|| code == FMA_EXPR)
{
! if (TREE_CODE_CLASS (code) == tcc_comparison)
t = TREE_TYPE (gimple_assign_rhs1 (stmt));
else
t = gimple_expr_type (stmt);
fp_operation = FLOAT_TYPE_P (t);
*************** stmt_could_throw_1_p (gimple *stmt)
*** 2759,2775 ****
honor_trapv = 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,
&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++)
if (tree_could_trap_p (gimple_op (stmt, i)))
return true;
--- 2756,2776 ----
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. */
ret = operation_could_trap_helper_p (code, fp_operation, honor_trapv,
! 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 = 1; i < gimple_num_ops (stmt); i++)
if (tree_could_trap_p (gimple_op (stmt, i)))
return true;
*************** stmt_could_throw_p (gimple *stmt)
*** 2795,2805 ****
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)
return false;
! return stmt_could_throw_1_p (stmt);
case GIMPLE_ASM:
if (!cfun->can_throw_non_call_exceptions)
--- 2796,2817 ----
case GIMPLE_CALL:
return !gimple_call_nothrow_p (as_a <gcall *> (stmt));
case GIMPLE_COND:
! {
! 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 (as_a <gassign *> (stmt));
case GIMPLE_ASM:
if (!cfun->can_throw_non_call_exceptions)
Index: gcc/testsuite/g++.dg/torture/pr80075.C
===================================================================
*** gcc/testsuite/g++.dg/torture/pr80075.C (nonexistent)
--- gcc/testsuite/g++.dg/torture/pr80075.C (working copy)
***************
*** 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;
+ }