aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/cp-gimplify.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/cp-gimplify.c')
-rw-r--r--gcc/cp/cp-gimplify.c76
1 files changed, 58 insertions, 18 deletions
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index a9a34cd81cc..177e2717aa5 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -264,7 +264,9 @@ genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
}
else
{
- location_t loc = EXPR_LOCATION (expr_first (body));
+ location_t loc = start_locus;
+ if (!cond || integer_nonzerop (cond))
+ loc = EXPR_LOCATION (expr_first (body));
if (loc == UNKNOWN_LOCATION)
loc = start_locus;
loop = build1_loc (loc, LOOP_EXPR, void_type_node, stmt_list);
@@ -1881,6 +1883,41 @@ cp_fully_fold (tree x)
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
+ C_MAYBE_CONST_EXPR. */
+
+tree
+c_fully_fold (tree x, bool /*in_init*/, bool */*maybe_const*/)
+{
+ /* 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;
/* This function tries to fold an expression X.
@@ -1897,6 +1934,7 @@ cp_fold (tree x)
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;
@@ -1920,6 +1958,7 @@ cp_fold (tree x)
break;
case VIEW_CONVERT_EXPR:
+ rval_ops = false;
case CONVERT_EXPR:
case NOP_EXPR:
case NON_LVALUE_EXPR:
@@ -1939,12 +1978,12 @@ cp_fold (tree x)
&& 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 = build1_loc (loc, code, TREE_TYPE (x), op0);
-
- x = fold (x);
+ x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
+ else
+ x = fold (x);
/* Conversion of an out-of-range value has implementation-defined
behavior; the language considers it different from arithmetic
@@ -1955,10 +1994,10 @@ cp_fold (tree x)
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:
@@ -1971,12 +2010,12 @@ cp_fold (tree x)
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 = build1_loc (loc, code, TREE_TYPE (x), op0);
-
- x = fold (x);
+ x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
+ else
+ x = fold (x);
gcc_assert (TREE_CODE (x) != COND_EXPR
|| !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))));
@@ -1988,7 +2027,7 @@ cp_fold (tree x)
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);
@@ -1998,6 +2037,8 @@ cp_fold (tree x)
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:
@@ -2033,11 +2074,10 @@ cp_fold (tree x)
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))))
@@ -2046,9 +2086,9 @@ cp_fold (tree x)
op0 = build_empty_stmt (loc);
if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1))
- x = build2_loc (loc, code, TREE_TYPE (x), op0, op1);
-
- x = fold (x);
+ x = fold_build2_loc (loc, code, TREE_TYPE (x), op0, op1);
+ else
+ x = fold (x);
if (TREE_CODE (x) == COMPOUND_EXPR && TREE_OPERAND (x, 0) == NULL_TREE
&& TREE_OPERAND (x, 1))
@@ -2059,7 +2099,7 @@ cp_fold (tree x)
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;