#include "stringpool.h"
#include "attribs.h"
#include "asan.h"
+#include "gimplify.h"
static tree cp_build_addr_expr_strict (tree, tsubst_flags_t);
static tree cp_build_function_call (tree, tree, tsubst_flags_t);
/* 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. */
- tree cond;
-
if (VOID_TYPE_P (TREE_TYPE (rhs)))
{
if (complain & tf_error)
if (!lvalue_or_else (lhs, lv_assign, complain))
return error_mark_node;
- 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);
+ tree op1 = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 1),
+ modifycode, rhs, complain);
+ /* When sanitizing undefined behavior, even when rhs doesn't need
+ stabilization at this point, the sanitization might add extra
+ SAVE_EXPRs in there and so make sure there is no tree sharing
+ in the rhs, otherwise those SAVE_EXPRs will have initialization
+ only in one of the two branches. */
+ if (sanitize_flags_p (SANITIZE_UNDEFINED
+ | SANITIZE_UNDEFINED_NONDEFAULT))
+ rhs = unshare_expr (rhs);
+ tree op2 = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 2),
+ modifycode, rhs, complain);
+ tree cond = build_conditional_expr (input_location,
+ TREE_OPERAND (lhs, 0), op1, op2,
+ complain);
if (cond == error_mark_node)
return cond;