This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix stmt_could_throw_1_p for constructor RHS


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]