&& C_TYPE_FIELDS_READONLY (TREE_TYPE (operand)))))
cxx_readonly_error (operand, lv_asm);
+ tree *op = &operand;
+ while (TREE_CODE (*op) == COMPOUND_EXPR)
+ op = &TREE_OPERAND (*op, 1);
+ switch (TREE_CODE (*op))
+ {
+ case PREINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case MODIFY_EXPR:
+ *op = genericize_compound_lvalue (*op);
+ op = &TREE_OPERAND (*op, 1);
+ break;
+ default:
+ break;
+ }
+
constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
oconstraints[i] = constraint;
{
/* If the operand is going to end up in memory,
mark it addressable. */
- if (!allows_reg && !cxx_mark_addressable (operand))
+ if (!allows_reg && !cxx_mark_addressable (*op))
operand = error_mark_node;
}
else
/* Strip the nops as we allow this case. FIXME, this really
should be rejected or made deprecated. */
STRIP_NOPS (operand);
- if (!cxx_mark_addressable (operand))
+
+ tree *op = &operand;
+ while (TREE_CODE (*op) == COMPOUND_EXPR)
+ op = &TREE_OPERAND (*op, 1);
+ switch (TREE_CODE (*op))
+ {
+ case PREINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case MODIFY_EXPR:
+ *op = genericize_compound_lvalue (*op);
+ op = &TREE_OPERAND (*op, 1);
+ break;
+ default:
+ break;
+ }
+
+ if (!cxx_mark_addressable (*op))
operand = error_mark_node;
}
else if (!allows_reg && !allows_mem)
return cp_build_unary_op (code, xarg, noconvert, tf_warning_or_error);
}
+/* Adjust LVALUE, an MODIFY_EXPR, PREINCREMENT_EXPR or PREDECREMENT_EXPR,
+ so that it is a valid lvalue even for GENERIC by replacing
+ (lhs = rhs) with ((lhs = rhs), lhs)
+ (--lhs) with ((--lhs), lhs)
+ (++lhs) with ((++lhs), lhs)
+ and if lhs has side-effects, calling cp_stabilize_reference on it, so
+ that it can be evaluated multiple times. */
+
+tree
+genericize_compound_lvalue (tree lvalue)
+{
+ if (TREE_SIDE_EFFECTS (TREE_OPERAND (lvalue, 0)))
+ lvalue = build2 (TREE_CODE (lvalue), TREE_TYPE (lvalue),
+ cp_stabilize_reference (TREE_OPERAND (lvalue, 0)),
+ TREE_OPERAND (lvalue, 1));
+ return build2 (COMPOUND_EXPR, TREE_TYPE (TREE_OPERAND (lvalue, 0)),
+ lvalue, TREE_OPERAND (lvalue, 0));
+}
+
/* Apply unary lvalue-demanding operator CODE to the expression ARG
for certain kinds of expressions which are not really lvalues
but which we can accept as lvalues.
if (TREE_CODE (arg) == MODIFY_EXPR
|| TREE_CODE (arg) == PREINCREMENT_EXPR
|| TREE_CODE (arg) == PREDECREMENT_EXPR)
- {
- tree lvalue = TREE_OPERAND (arg, 0);
- if (TREE_SIDE_EFFECTS (lvalue))
- {
- lvalue = cp_stabilize_reference (lvalue);
- arg = build2 (TREE_CODE (arg), TREE_TYPE (arg),
- lvalue, TREE_OPERAND (arg, 1));
- }
- return unary_complex_lvalue
- (code, build2 (COMPOUND_EXPR, TREE_TYPE (lvalue), arg, lvalue));
- }
+ return unary_complex_lvalue (code, genericize_compound_lvalue (arg));
if (code != ADDR_EXPR)
return NULL_TREE;
case PREINCREMENT_EXPR:
if (compound_side_effects_p)
newrhs = rhs = stabilize_expr (rhs, &preeval);
- if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
- lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
- cp_stabilize_reference (TREE_OPERAND (lhs, 0)),
- TREE_OPERAND (lhs, 1));
- lhs = build2 (COMPOUND_EXPR, lhstype, lhs, TREE_OPERAND (lhs, 0));
+ lhs = genericize_compound_lvalue (lhs);
maybe_add_compound:
/* If we had (bar, --foo) = 5; or (bar, (baz, --foo)) = 5;
and looked through the COMPOUND_EXPRs, readd them now around
case MODIFY_EXPR:
if (compound_side_effects_p)
newrhs = rhs = stabilize_expr (rhs, &preeval);
- if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
- lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
- cp_stabilize_reference (TREE_OPERAND (lhs, 0)),
- TREE_OPERAND (lhs, 1));
- lhs = build2 (COMPOUND_EXPR, lhstype, lhs, TREE_OPERAND (lhs, 0));
+ lhs = genericize_compound_lvalue (lhs);
goto maybe_add_compound;
case MIN_EXPR: