https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95221
Jason Merrill <jason at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Last reconfirmed| |2020-05-20 Status|UNCONFIRMED |NEW --- Comment #6 from Jason Merrill <jason at gcc dot gnu.org> --- (In reply to Marek Polacek from comment #2) > I think the thing is that we have a CALL_EXPR, something like > > OBJ_TYPE_REF (...) (.UBSAN_VPTR ()) > > and now we first evaluate the OBJ_TYPE_REF. Yep, that's the problem. We're currently sanitizing the vtable when determining the 'this' argument to the function, separately from looking at the vtable in order to determine which function to call. In C++14 we evaluate 'this' first, in C++17 we evaluate the function first. build_over_call tries to share any side-effects between the 'this' and the OBJ_TYPE_REF with a save_expr, but then cp_ubsan_maybe_instrument_member_call adds the sanitization only to the 'this' argument, breaking that sharing and introducing a fragile order dependency. A simple fix might be to not preevaluate when CALL_EXPR_FN is an OBJ_TYPE_REF, as the sharing above should mean that side-effects happen when the object argument is evaluated, which should be what we want. It occurs to me that the current preevaluation is wrong for a virtual assignment when CALL_EXPR_REVERSE_ARGS is set.