re PR c++/80075 (ICE: "statement marked for throw, but doesn’t" with -fnon-call-excep...
authorRichard Biener <rguenther@suse.de>
Fri, 17 Mar 2017 12:48:56 +0000 (12:48 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 17 Mar 2017 12:48:56 +0000 (12:48 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr80075.C [new file with mode: 0644]
gcc/tree-eh.c

index 76da3f1..9af5815 100644 (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.
index 72c74df..144030e 100644 (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
diff --git a/gcc/testsuite/g++.dg/torture/pr80075.C b/gcc/testsuite/g++.dg/torture/pr80075.C
new file mode 100644 (file)
index 0000000..5bc8020
--- /dev/null
@@ -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;
+}
index 0b785e9..fc016d7 100644 (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)