return cp_fold (x);
}
+/* Fold expression X which is used as an rvalue if RVAL is true. */
+
+static tree
+cp_fold_maybe_rvalue (tree x, bool rval)
+{
+ if (rval && DECL_P (x))
+ {
+ tree v = decl_constant_value (x);
+ if (v != error_mark_node)
+ x = v;
+ }
+ return cp_fold (x);
+}
+
+/* Fold expression X which is used as an rvalue. */
+
+static tree
+cp_fold_rvalue (tree x)
+{
+ return cp_fold_maybe_rvalue (x, true);
+}
+
/* c-common interface to cp_fold. If IN_INIT, this is in a static initializer
and certain changes are made to the folding done. Or should be (FIXME). We
never touch maybe_const, as it is only used for the C front-end
tree
c_fully_fold (tree x, bool /*in_init*/, bool */*maybe_const*/)
{
- return cp_fold (x);
+ /* c_fully_fold is only used on rvalues, and we need to fold CONST_DECL to
+ INTEGER_CST. */
+ return cp_fold_rvalue (x);
}
static GTY((cache, deletable)) cache_map fold_cache;
tree org_x = x, r = NULL_TREE;
enum tree_code code;
location_t loc;
+ bool rval_ops = true;
if (!x || error_operand_p (x))
return x;
break;
case VIEW_CONVERT_EXPR:
+ rval_ops = false;
case CONVERT_EXPR:
case NOP_EXPR:
case NON_LVALUE_EXPR:
&& TREE_TYPE (x) == TREE_TYPE (op0))
return x;
- op0 = cp_fold (op0);
+ op0 = cp_fold_maybe_rvalue (op0, rval_ops);
if (op0 != TREE_OPERAND (x, 0))
x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
break;
- case SAVE_EXPR:
case ADDR_EXPR:
case REALPART_EXPR:
case IMAGPART_EXPR:
+ rval_ops = false;
case CONJ_EXPR:
case FIX_TRUNC_EXPR:
case FLOAT_EXPR:
case INDIRECT_REF:
loc = EXPR_LOCATION (x);
- op0 = cp_fold (TREE_OPERAND (x, 0));
+ op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops);
if (op0 != TREE_OPERAND (x, 0))
x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
loc = EXPR_LOCATION (x);
op0 = cp_fold (TREE_OPERAND (x, 0));
- op1 = cp_fold (TREE_OPERAND (x, 1));
+ op1 = cp_fold_rvalue (TREE_OPERAND (x, 1));
if (TREE_OPERAND (x, 0) != op0 || TREE_OPERAND (x, 1) != op1)
x = build2_loc (loc, code, TREE_TYPE (x), op0, op1);
case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR:
case COMPOUND_EXPR:
+ case MODIFY_EXPR:
+ rval_ops = false;
case POINTER_PLUS_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
case UNGT_EXPR: case UNGE_EXPR:
case UNEQ_EXPR: case LTGT_EXPR:
case RANGE_EXPR: case COMPLEX_EXPR:
- case MODIFY_EXPR:
loc = EXPR_LOCATION (x);
- op0 = cp_fold (TREE_OPERAND (x, 0));
- op1 = cp_fold (TREE_OPERAND (x, 1));
+ op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops);
+ op1 = cp_fold_rvalue (TREE_OPERAND (x, 1));
if ((code == COMPOUND_EXPR || code == MODIFY_EXPR)
&& ((op1 && TREE_SIDE_EFFECTS (op1))
|| (op0 && TREE_SIDE_EFFECTS (op0))))
case COND_EXPR:
loc = EXPR_LOCATION (x);
- op0 = cp_fold (TREE_OPERAND (x, 0));
+ op0 = cp_fold_rvalue (TREE_OPERAND (x, 0));
if (TREE_SIDE_EFFECTS (op0))
break;