Hi! The SAVE_EXPR was needed here only in the previous implementation where we emitted more code inline early, now that we have UBSAN_VPTR internal call that is lowered during sanopt, we use it just once. Furthermore, the SAVE_EXPR caused e.g. the following two testcases to misbehave, as a shared CALL_EXPR tree of a destructor call containing the UBSA_VPTR with SAVE_EXPR was gimplified in two places - in one finally and another cleanup. As the finally wasn't dominating the cleanup (obviously we don't want to destruct twice), the SAVE_EXPR was initialized in one place and we had uninitialized var in the other spot.
Fixed by not wrapping the vptr load into a SAVE_EXPR. Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk. 2015-01-29 Jakub Jelinek <ja...@redhat.com> PR c++/64717 * cp-ubsan.c (cp_ubsan_instrument_vptr): Don't wrap vptr into SAVE_EXPR. * g++.dg/ubsan/pr64717-1.C: New test. * g++.dg/ubsan/pr64717-2.C: New test. --- gcc/cp/cp-ubsan.c.jj 2015-01-15 23:57:07.000000000 +0100 +++ gcc/cp/cp-ubsan.c 2015-01-29 17:57:11.134236397 +0100 @@ -107,7 +107,6 @@ cp_ubsan_instrument_vptr (location_t loc fold_build2 (NE_EXPR, boolean_type_node, op, build_zero_cst (TREE_TYPE (op))), vptr, build_int_cst (uint64_type_node, 0)); - vptr = build1_loc (loc, SAVE_EXPR, uint64_type_node, vptr); tree ti_decl = get_tinfo_decl (type); mark_used (ti_decl); tree ptype = build_pointer_type (type); --- gcc/testsuite/g++.dg/ubsan/pr64717-1.C.jj 2015-01-29 18:03:14.428052606 +0100 +++ gcc/testsuite/g++.dg/ubsan/pr64717-1.C 2015-01-29 18:02:39.000000000 +0100 @@ -0,0 +1,15 @@ +// PR c++/64717 +// { dg-do compile } +// { dg-options "-O2 -Wuninitialized -fsanitize=vptr" } + +class Foo {}; +Foo make_foo (); + +struct Handle { virtual ~Handle (); }; +Handle open (Foo); + +void +bar () +{ + Handle file (open (make_foo ())); // { dg-bogus "is used uninitialized" } +} --- gcc/testsuite/g++.dg/ubsan/pr64717-2.C.jj 2015-01-29 18:03:17.488000521 +0100 +++ gcc/testsuite/g++.dg/ubsan/pr64717-2.C 2015-01-29 18:02:32.000000000 +0100 @@ -0,0 +1,20 @@ +// PR c++/64717 +// { dg-do compile } +// { dg-options "-O2 -Wuninitialized -fsanitize=vptr" } + +class ios {}; + +struct stringstream : virtual ios { + stringstream (char *); + ~stringstream (); +}; + +struct string { char *c_str (); }; + +string make_str (); + +void +bar () +{ + stringstream param (make_str ().c_str ()); // { dg-bogus "is used uninitialized" } +} Jakub