https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89869
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The problem is that for the COND_EXPR as lvalue, cp_build_modify_expr does: /* Handle (a ? b : c) used as an "lvalue". */ case COND_EXPR: { /* Produce (a ? (b = rhs) : (c = rhs)) except that the RHS goes through a save-expr so the code to compute it is only emitted once. */ It uses stabilize_expr on the rhs, but this is before ubsan instrumentation, so there is nothing to stabilize. And then we emit: cond = build_conditional_expr (input_location, TREE_OPERAND (lhs, 0), cp_build_modify_expr (loc, TREE_OPERAND (lhs, 1), modifycode, rhs, complain), cp_build_modify_expr (loc, TREE_OPERAND (lhs, 2), modifycode, rhs, complain), complain); so rhs is a tree shared in two COND_EXPR branches. And then we later instrument this and wrap in a SAVE_EXPR for VPTR instrumentation.