On Tue, 18 Nov 2014, Jakub Jelinek wrote: > Hi! > > This patch fixes instrumentation of bool/enum loads if they could > throw. We want to keep the EH on the load, and push > further statements on the fallthru edge. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2014-11-18 Jakub Jelinek <ja...@redhat.com> > > 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. > > --- gcc/ubsan.c.jj 2014-11-14 15:11:49.000000000 +0100 > +++ gcc/ubsan.c 2014-11-18 09:29:20.409209556 +0100 > @@ -67,6 +67,7 @@ along with GCC; see the file COPYING3. > #include "dfp.h" > #include "builtins.h" > #include "tree-object-size.h" > +#include "tree-eh.h" > > /* Map from a tree to a VAR_DECL tree. */ > > @@ -1135,7 +1136,9 @@ instrument_bool_enum_load (gimple_stmt_i > || 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), > @@ -1145,9 +1148,24 @@ instrument_bool_enum_load (gimple_stmt_i > 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_with_ops (gsi, MEM_REF, mem, NULL_TREE);
Please use gimple_assign_set_rhs_from_tree for single-rhs trees. Ok with that change. Thanks, RIchard. > + 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)) > @@ -1169,8 +1187,11 @@ instrument_bool_enum_load (gimple_stmt_i > 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) > --- gcc/testsuite/g++.dg/ubsan/pr63913.C.jj 2014-11-18 09:34:10.603981487 > +0100 > +++ gcc/testsuite/g++.dg/ubsan/pr63913.C 2014-11-18 09:33:47.000000000 > +0100 > @@ -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; > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendoerffer, HRB 21284 (AG Nuernberg) Maxfeldstrasse 5, 90409 Nuernberg, Germany