aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/utils2.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/gcc-interface/utils2.c')
-rw-r--r--gcc/ada/gcc-interface/utils2.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c
index 83cc794..3bf0e15 100644
--- a/gcc/ada/gcc-interface/utils2.c
+++ b/gcc/ada/gcc-interface/utils2.c
@@ -1301,11 +1301,11 @@ build_binary_op (enum tree_code op_code, tree result_type,
if (TYPE_VOLATILE (operation_type))
TREE_THIS_VOLATILE (result) = 1;
}
- else
- TREE_CONSTANT (result)
- |= (TREE_CONSTANT (left_operand) && TREE_CONSTANT (right_operand));
+ else if (TREE_CONSTANT (left_operand) && TREE_CONSTANT (right_operand))
+ TREE_CONSTANT (result) = 1;
- TREE_SIDE_EFFECTS (result) |= has_side_effects;
+ if (has_side_effects)
+ TREE_SIDE_EFFECTS (result) = 1;
/* If we are working with modular types, perform the MOD operation
if something above hasn't eliminated the need for it. */
@@ -1528,7 +1528,9 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand)
result = build_fold_addr_expr (operand);
}
- TREE_CONSTANT (result) = staticp (operand) || TREE_CONSTANT (operand);
+ if (TREE_CONSTANT (operand) || staticp (operand))
+ TREE_CONSTANT (result) = 1;
+
break;
case INDIRECT_REF:
@@ -1957,14 +1959,19 @@ gnat_build_constructor (tree type, vec<constructor_elt, va_gc> *v)
the elements along the way for possible sorting purposes below. */
FOR_EACH_CONSTRUCTOR_ELT (v, n_elmts, obj, val)
{
- /* The predicate must be in keeping with output_constructor. */
+ /* The predicate must be in keeping with output_constructor and, unlike
+ initializer_constant_valid_p, we accept "&{...}" because we'll put
+ the CONSTRUCTOR into the constant pool during gimplification. */
if ((!TREE_CONSTANT (val) && !TREE_STATIC (val))
|| (TREE_CODE (type) == RECORD_TYPE
&& CONSTRUCTOR_BITFIELD_P (obj)
&& !initializer_constant_valid_for_bitfield_p (val))
- || !initializer_constant_valid_p (val,
- TREE_TYPE (val),
- TYPE_REVERSE_STORAGE_ORDER (type)))
+ || (!initializer_constant_valid_p (val,
+ TREE_TYPE (val),
+ TYPE_REVERSE_STORAGE_ORDER (type))
+ && !(TREE_CODE (val) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (val, 0)) == CONSTRUCTOR
+ && TREE_CONSTANT (TREE_OPERAND (val, 0)))))
allconstant = false;
if (!TREE_READONLY (val))
@@ -2676,10 +2683,13 @@ gnat_stabilize_reference_1 (tree e, void *data)
gcc_unreachable ();
}
+ /* See gnat_rewrite_reference below for the rationale. */
TREE_READONLY (result) = TREE_READONLY (e);
- TREE_SIDE_EFFECTS (result) |= TREE_SIDE_EFFECTS (e);
TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
+ if (TREE_SIDE_EFFECTS (e))
+ TREE_SIDE_EFFECTS (result) = 1;
+
return result;
}
@@ -2796,18 +2806,18 @@ gnat_rewrite_reference (tree ref, rewrite_fn func, void *data, tree *init)
gcc_unreachable ();
}
- /* TREE_THIS_VOLATILE and TREE_SIDE_EFFECTS set on the initial expression
- may not be sustained across some paths, such as the way via build1 for
- INDIRECT_REF. We reset those flags here in the general case, which is
- consistent with the GCC version of this routine.
+ /* TREE_READONLY and TREE_THIS_VOLATILE set on the initial expression may
+ not be sustained across some paths, such as the one for INDIRECT_REF.
Special care should be taken regarding TREE_SIDE_EFFECTS, because some
paths introduce side-effects where there was none initially (e.g. if a
SAVE_EXPR is built) and we also want to keep track of that. */
TREE_READONLY (result) = TREE_READONLY (ref);
- TREE_SIDE_EFFECTS (result) |= TREE_SIDE_EFFECTS (ref);
TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
+ if (TREE_SIDE_EFFECTS (ref))
+ TREE_SIDE_EFFECTS (result) = 1;
+
if (code == INDIRECT_REF
|| code == UNCONSTRAINED_ARRAY_REF
|| code == ARRAY_REF