re PR sanitizer/63913 (ICE: verify_gimple failed: statement marked for throw, but...
authorJakub Jelinek <jakub@redhat.com>
Wed, 19 Nov 2014 09:27:30 +0000 (10:27 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 19 Nov 2014 09:27:30 +0000 (10:27 +0100)
PR sanitizer/63913
* ubsan.c: Include tree-eh.h.
(instrument_bool_enum_load): Handle loads that can throw.

* g++.dg/ubsan/pr63913.C: New test.

From-SVN: r217755

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ubsan/pr63913.C [new file with mode: 0644]
gcc/ubsan.c

index b1bb78ffb0e745df257a7d201c12afd662d1a1eb..f81db234c5d9b389cb623785fca1441b22a8e92f 100644 (file)
@@ -1,5 +1,9 @@
 2014-11-19  Jakub Jelinek  <jakub@redhat.com>
 
+       PR sanitizer/63913
+       * ubsan.c: Include tree-eh.h.
+       (instrument_bool_enum_load): Handle loads that can throw.
+
        PR rtl-optimization/63843
        * simplify-rtx.c (simplify_binary_operation_1) <case ASHIFTRT>: For
        optimization of ashiftrt of subreg of lshiftrt, check that code
index 0d84fe280b6e104cf5bf38cf82e907669d8c735e..19b6c01b78fbd47f5258dc014213e62f11249e79 100644 (file)
@@ -1,3 +1,8 @@
+2014-11-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/63913
+       * g++.dg/ubsan/pr63913.C: New test.
+
 2014-11-19  Andreas Schwab  <schwab@suse.de>
 
        * gcc.dg/pure-2.c: Update line numbers.
diff --git a/gcc/testsuite/g++.dg/ubsan/pr63913.C b/gcc/testsuite/g++.dg/ubsan/pr63913.C
new file mode 100644 (file)
index 0000000..34dceb4
--- /dev/null
@@ -0,0 +1,12 @@
+// PR sanitizer/63913
+// { dg-do compile }
+// { dg-options "-fsanitize=bool -fnon-call-exceptions" }
+
+struct B { B (); ~B (); };
+
+double
+foo (bool *x)
+{
+  B b;
+  return *x;
+}
index 98a6c2face7ad05d281056e0c46f2b1b0d579fa3..7d1e341812ceeb118b6e5725de1aa9d9b210e3b0 100644 (file)
@@ -67,6 +67,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dfp.h"
 #include "builtins.h"
 #include "tree-object-size.h"
+#include "tree-eh.h"
 
 /* Map from a tree to a VAR_DECL tree.  */
 
@@ -1159,7 +1160,9 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi)
       || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
     return;
 
+  bool can_throw = stmt_could_throw_p (stmt);
   location_t loc = gimple_location (stmt);
+  tree lhs = gimple_assign_lhs (stmt);
   tree ptype = build_pointer_type (TREE_TYPE (rhs));
   tree atype = reference_alias_ptr_type (rhs);
   gimple g = gimple_build_assign (make_ssa_name (ptype, NULL),
@@ -1169,9 +1172,24 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi)
   tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
                     build_int_cst (atype, 0));
   tree urhs = make_ssa_name (utype, NULL);
-  g = gimple_build_assign (urhs, mem);
-  gimple_set_location (g, loc);
-  gsi_insert_before (gsi, g, GSI_SAME_STMT);
+  if (can_throw)
+    {
+      gimple_assign_set_lhs (stmt, urhs);
+      g = gimple_build_assign_with_ops (NOP_EXPR, lhs, urhs, NULL_TREE);
+      gimple_set_location (g, loc);
+      edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
+      gsi_insert_on_edge_immediate (e, g);
+      gimple_assign_set_rhs_from_tree (gsi, mem);
+      update_stmt (stmt);
+      *gsi = gsi_for_stmt (g);
+      g = stmt;
+    }
+  else
+    {
+      g = gimple_build_assign (urhs, mem);
+      gimple_set_location (g, loc);
+      gsi_insert_before (gsi, g, GSI_SAME_STMT);
+    }
   minv = fold_convert (utype, minv);
   maxv = fold_convert (utype, maxv);
   if (!integer_zerop (minv))
@@ -1193,8 +1211,11 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi)
   gimple_set_location (g, loc);
   gsi_insert_after (gsi, g, GSI_NEW_STMT);
 
-  gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs, NULL_TREE);
-  update_stmt (stmt);
+  if (!can_throw)
+    {
+      gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs, NULL_TREE);
+      update_stmt (stmt);
+    }
 
   gsi2 = gsi_after_labels (then_bb);
   if (flag_sanitize_undefined_trap_on_error)