diff options
author | Jakub Jelinek <jakub@redhat.com> | 2014-11-19 10:27:30 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-11-19 10:27:30 +0100 |
commit | d4698839555ad0f855f68347658231f04d0061a5 (patch) | |
tree | 532cc91f7e101e19ad224580a7f49ac2a319bc88 | |
parent | 8f7d0ab920d2863472c4899e6a9222400d1c9a89 (diff) | |
download | gcc-d4698839555ad0f855f68347658231f04d0061a5.zip gcc-d4698839555ad0f855f68347658231f04d0061a5.tar.gz gcc-d4698839555ad0f855f68347658231f04d0061a5.tar.bz2 |
re PR sanitizer/63913 (ICE: verify_gimple failed: statement marked for throw, but doesn't with -fnon-call-exceptions -fsanitize=bool)
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
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ubsan/pr63913.C | 12 | ||||
-rw-r--r-- | gcc/ubsan.c | 31 |
4 files changed, 47 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b1bb78f..f81db23 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0d84fe2..19b6c01 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..34dceb4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr63913.C @@ -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; +} diff --git a/gcc/ubsan.c b/gcc/ubsan.c index 98a6c2f..7d1e341 100644 --- a/gcc/ubsan.c +++ b/gcc/ubsan.c @@ -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) |