TREE_TYPE (result) = type = build_pointer_type (type);
break;
+ case COMPOUND_EXPR:
+ /* Fold a compound expression if it has unconstrained array type
+ since the middle-end cannot handle it. But we don't it in the
+ general case because it may introduce aliasing issues if the
+ first operand is an indirect assignment and the second operand
+ the corresponding address, e.g. for an allocator. */
+ if (TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE)
+ {
+ result = build_unary_op (ADDR_EXPR, result_type,
+ TREE_OPERAND (operand, 1));
+ result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
+ TREE_OPERAND (operand, 0), result);
+ break;
+ }
+ goto common;
+
case ARRAY_REF:
case ARRAY_RANGE_REF:
case COMPONENT_REF:
/* If the result type is unconstrained, take the address of the operands and
then dereference the result. Likewise if the result type is passed by
- reference because creating a temporary of this type is not allowed. */
+ reference, but this is natively handled in the gimplifier. */
if (TREE_CODE (result_type) == UNCONSTRAINED_ARRAY_TYPE
- || CONTAINS_PLACEHOLDER_P (TYPE_SIZE (result_type))
- || (AGGREGATE_TYPE_P (result_type) && TYPE_BY_REFERENCE_P (result_type)))
+ || CONTAINS_PLACEHOLDER_P (TYPE_SIZE (result_type)))
{
result_type = build_pointer_type (result_type);
true_operand = build_unary_op (ADDR_EXPR, result_type, true_operand);
tree new_field;
/* First loop thru normal components. */
-
for (new_field = TYPE_FIELDS (record_type); new_field;
new_field = TREE_CHAIN (new_field))
- if (field == new_field
- || DECL_ORIGINAL_FIELD (new_field) == field
- || new_field == DECL_ORIGINAL_FIELD (field)
- || (DECL_ORIGINAL_FIELD (field)
- && (DECL_ORIGINAL_FIELD (field)
- == DECL_ORIGINAL_FIELD (new_field))))
+ if (SAME_FIELD_P (field, new_field))
break;
/* Next, loop thru DECL_INTERNAL_P components if we haven't found
the component in the first search. Doing this search in 2 steps
is required to avoiding hidden homonymous fields in the
_Parent field. */
-
if (!new_field)
for (new_field = TYPE_FIELDS (record_type); new_field;
new_field = TREE_CHAIN (new_field))
tree aligning_field
= build_component_ref (aligning_record, NULL_TREE,
- TYPE_FIELDS (aligning_type), 0);
+ TYPE_FIELDS (aligning_type), false);
tree aligning_field_addr
= build_unary_op (ADDR_EXPR, NULL_TREE, aligning_field);
build_component_ref
(build_unary_op (INDIRECT_REF, NULL_TREE,
convert (storage_ptr_type, storage)),
- NULL_TREE, TYPE_FIELDS (storage_type), 0),
+ NULL_TREE, TYPE_FIELDS (storage_type), false),
build_template (template_type, type, NULL_TREE)),
convert (result_type, convert (storage_ptr_type, storage)));
}
t = TREE_OPERAND (t, 0);
break;
+ case COMPOUND_EXPR:
+ t = TREE_OPERAND (t, 1);
+ break;
+
case CONSTRUCTOR:
TREE_ADDRESSABLE (t) = 1;
return true;
break;
case CALL_EXPR:
- case COMPOUND_EXPR:
result = gnat_stabilize_reference_1 (ref, force);
break;
+ case COMPOUND_EXPR:
+ result = build2 (COMPOUND_EXPR, type,
+ gnat_stabilize_reference (TREE_OPERAND (ref, 0), force,
+ success),
+ gnat_stabilize_reference_1 (TREE_OPERAND (ref, 1),
+ force));
+ break;
+
case CONSTRUCTOR:
/* Constructors with 1 element are used extensively to formally
convert objects to special wrapping types. */