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.c137
1 files changed, 26 insertions, 111 deletions
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index c0ee8e43466..5c4d3c1bb1f 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -1851,38 +1851,6 @@ cxx_omp_disregard_value_expr (tree decl, bool shared)
&& DECL_OMP_PRIVATIZED_MEMBER (decl);
}
-/* Callback for walk_tree, looking for LABEL_EXPR. Return *TP if it is
- a LABEL_EXPR; otherwise return NULL_TREE. Do not check the subtrees
- of GOTO_EXPR. */
-
-static tree
-contains_label_1 (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
-{
- switch (TREE_CODE (*tp))
- {
- case LABEL_EXPR:
- return *tp;
-
- case GOTO_EXPR:
- *walk_subtrees = 0;
-
- /* ... fall through ... */
-
- default:
- return NULL_TREE;
- }
-}
-
-/* Return whether the sub-tree ST contains a label which is accessible from
- outside the sub-tree. */
-
-static bool
-contains_label_p (tree st)
-{
- return
- walk_tree_without_duplicates (&st, contains_label_1 , NULL) != NULL_TREE;
-}
-
/* Perform folding on expression X. */
tree
@@ -1974,19 +1942,8 @@ cp_fold (tree x)
if (VOID_TYPE_P (TREE_TYPE (x)))
return x;
- if (!TREE_OPERAND (x, 0)
- || TREE_CODE (TREE_OPERAND (x, 0)) == NON_LVALUE_EXPR)
- return x;
-
loc = EXPR_LOCATION (x);
- op0 = TREE_OPERAND (x, 0);
-
- if (TREE_CODE (x) == NOP_EXPR
- && TREE_OVERFLOW_P (op0)
- && TREE_TYPE (x) == TREE_TYPE (op0))
- return x;
-
- op0 = cp_fold_maybe_rvalue (op0, rval_ops);
+ 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);
@@ -2032,16 +1989,6 @@ cp_fold (tree x)
case POSTDECREMENT_EXPR:
case POSTINCREMENT_EXPR:
case INIT_EXPR:
-
- loc = EXPR_LOCATION (x);
- op0 = cp_fold (TREE_OPERAND (x, 0));
- 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);
-
- break;
-
case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR:
case COMPOUND_EXPR:
@@ -2086,78 +2033,33 @@ cp_fold (tree x)
loc = EXPR_LOCATION (x);
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))))
- {
- if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1))
- x = build2_loc (loc, code, TREE_TYPE (x), op0, op1);
- break;
- }
- if (TREE_CODE (x) == COMPOUND_EXPR && !op0)
- op0 = build_empty_stmt (loc);
if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1))
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))
- return TREE_OPERAND (x, 1);
break;
case VEC_COND_EXPR:
case COND_EXPR:
+ /* Don't bother folding a void condition, since it can't produce a
+ constant value. Also, some statement-level uses of COND_EXPR leave
+ one of the branches NULL, so folding would crash. */
+ if (VOID_TYPE_P (TREE_TYPE (x)))
+ return x;
+
loc = EXPR_LOCATION (x);
op0 = cp_fold_rvalue (TREE_OPERAND (x, 0));
-
- if (TREE_SIDE_EFFECTS (op0))
- break;
-
op1 = cp_fold (TREE_OPERAND (x, 1));
op2 = cp_fold (TREE_OPERAND (x, 2));
- if (TREE_CODE (op0) == INTEGER_CST)
- {
- tree un;
-
- if (integer_zerop (op0))
- {
- un = op1;
- r = op2;
- }
- else
- {
- un = op2;
- r = op1;
- }
-
- if ((!TREE_SIDE_EFFECTS (un) || !contains_label_p (un))
- && (! VOID_TYPE_P (TREE_TYPE (r)) || VOID_TYPE_P (x)))
- {
- if (CAN_HAVE_LOCATION_P (r)
- && EXPR_LOCATION (r) != loc
- && !(TREE_CODE (r) == SAVE_EXPR
- || TREE_CODE (r) == TARGET_EXPR
- || TREE_CODE (r) == BIND_EXPR))
- {
- r = copy_node (r);
- SET_EXPR_LOCATION (r, loc);
- }
- x = r;
- }
-
- break;
- }
-
- if (VOID_TYPE_P (TREE_TYPE (x)))
- break;
-
- x = build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
-
- if (code != COND_EXPR)
+ if (op0 != TREE_OPERAND (x, 0)
+ || op1 != TREE_OPERAND (x, 1)
+ || op2 != TREE_OPERAND (x, 2))
+ x = fold_build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
+ else
x = fold (x);
break;
@@ -2223,9 +2125,22 @@ cp_fold (tree x)
{
unsigned i;
constructor_elt *p;
+ bool changed = false;
vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (x);
+ vec<constructor_elt, va_gc> *nelts = NULL;
+ vec_safe_reserve (nelts, vec_safe_length (elts));
FOR_EACH_VEC_SAFE_ELT (elts, i, p)
- p->value = cp_fold (p->value);
+ {
+ tree op = cp_fold (p->value);
+ constructor_elt e = { p->index, op };
+ nelts->quick_push (e);
+ if (op != p->value)
+ changed = true;
+ }
+ if (changed)
+ x = build_constructor (TREE_TYPE (x), nelts);
+ else
+ vec_free (nelts);
break;
}
case TREE_VEC: