tree lhs_type = TREE_TYPE (lhs);
tree lhs_addr = build_unary_op (loc, ADDR_EXPR, lhs, false);
tree seq_cst = build_int_cst (integer_type_node, MEMMODEL_SEQ_CST);
- tree rhs_type = TREE_TYPE (rhs);
+ tree rhs_semantic_type = TREE_TYPE (rhs);
+ tree nonatomic_rhs_semantic_type;
+ tree rhs_type;
gcc_assert (TYPE_ATOMIC (lhs_type));
with a loop. */
compound_stmt = c_begin_compound_stmt (false);
+ /* Remove any excess precision (which is only present here in the
+ case of compound assignments). */
+ if (TREE_CODE (rhs) == EXCESS_PRECISION_EXPR)
+ {
+ gcc_assert (modifycode != NOP_EXPR);
+ rhs = TREE_OPERAND (rhs, 0);
+ }
+ rhs_type = TREE_TYPE (rhs);
+
/* Fold the RHS if it hasn't already been folded. */
if (modifycode != NOP_EXPR)
rhs = c_fully_fold (rhs, false, NULL);
the VAL temp variable to hold the RHS. */
nonatomic_lhs_type = build_qualified_type (lhs_type, TYPE_UNQUALIFIED);
nonatomic_rhs_type = build_qualified_type (rhs_type, TYPE_UNQUALIFIED);
+ nonatomic_rhs_semantic_type = build_qualified_type (rhs_semantic_type,
+ TYPE_UNQUALIFIED);
val = create_tmp_var_raw (nonatomic_rhs_type);
TREE_ADDRESSABLE (val) = 1;
TREE_NO_WARNING (val) = 1;
add_stmt (loop_label);
/* newval = old + val; */
+ if (rhs_type != rhs_semantic_type)
+ val = build1 (EXCESS_PRECISION_EXPR, nonatomic_rhs_semantic_type, val);
rhs = build_binary_op (loc, modifycode, old, val, true);
- rhs = c_fully_fold (rhs, false, NULL);
+ if (TREE_CODE (rhs) == EXCESS_PRECISION_EXPR)
+ {
+ tree eptype = TREE_TYPE (rhs);
+ rhs = c_fully_fold (TREE_OPERAND (rhs, 0), false, NULL);
+ rhs = build1 (EXCESS_PRECISION_EXPR, eptype, rhs);
+ }
+ else
+ rhs = c_fully_fold (rhs, false, NULL);
rhs = convert_for_assignment (loc, UNKNOWN_LOCATION, nonatomic_lhs_type,
rhs, NULL_TREE, ic_assign, false, NULL_TREE,
NULL_TREE, 0);
tree result;
tree newrhs;
tree rhseval = NULL_TREE;
- tree rhs_semantic_type = NULL_TREE;
tree lhstype = TREE_TYPE (lhs);
tree olhstype = lhstype;
bool npc;
is_atomic_op = really_atomic_lvalue (lhs);
- if (TREE_CODE (rhs) == EXCESS_PRECISION_EXPR)
- {
- rhs_semantic_type = TREE_TYPE (rhs);
- rhs = TREE_OPERAND (rhs, 0);
- }
-
newrhs = rhs;
if (TREE_CODE (lhs) == C_MAYBE_CONST_EXPR)
that modify LHS. */
if (TREE_SIDE_EFFECTS (rhs))
{
- newrhs = save_expr (rhs);
+ if (TREE_CODE (rhs) == EXCESS_PRECISION_EXPR)
+ newrhs = save_expr (TREE_OPERAND (rhs, 0));
+ else
+ newrhs = save_expr (rhs);
rhseval = newrhs;
+ if (TREE_CODE (rhs) == EXCESS_PRECISION_EXPR)
+ newrhs = build1 (EXCESS_PRECISION_EXPR, TREE_TYPE (rhs),
+ newrhs);
}
newrhs = build_binary_op (location,
modifycode, lhs, newrhs, true);
{
/* Check if we are modifying an Objective-C property reference;
if so, we need to generate setter calls. */
- result = objc_maybe_build_modify_expr (lhs, newrhs);
+ if (TREE_CODE (newrhs) == EXCESS_PRECISION_EXPR)
+ result = objc_maybe_build_modify_expr (lhs, TREE_OPERAND (newrhs, 0));
+ else
+ result = objc_maybe_build_modify_expr (lhs, newrhs);
if (result)
goto return_result;
if (!(is_atomic_op && modifycode != NOP_EXPR))
{
+ tree rhs_semantic_type = NULL_TREE;
+ if (TREE_CODE (newrhs) == EXCESS_PRECISION_EXPR)
+ {
+ rhs_semantic_type = TREE_TYPE (newrhs);
+ newrhs = TREE_OPERAND (newrhs, 0);
+ }
npc = null_pointer_constant_p (newrhs);
newrhs = c_fully_fold (newrhs, false, NULL);
if (rhs_semantic_type)