Ada: Fix wrong 'Access to aliased constrained array of controlled type
For technical reasons, the recently reimplemented finalization machinery for controlled types requires arrays of controlled types to be allocated with their bounds, including in the case where their nominal subtype is constrained. However, in this case, the type of 'Access for the arrays is pointer-to-constrained-array and, therefore, its value must designate the array itself and not the bounds. gcc/ada/ * gcc-interface/utils.cc (convert) <POINTER_TYPE>: Use fold_convert to convert between thin pointers. If the source is a thin pointer with zero offset from the base and the target is a pointer to its array, displace the pointer after converting it. * gcc-interface/utils2.cc (build_unary_op) <ATTR_ADDR_EXPR>: Use fold_convert to convert the address before displacing it.
This commit is contained in:
parent
0c63c7524b
commit
f085dbf97e
2 changed files with 22 additions and 6 deletions
|
@ -5259,7 +5259,7 @@ convert (tree type, tree expr)
|
|||
: size_zero_node;
|
||||
tree byte_diff = size_diffop (type_pos, etype_pos);
|
||||
|
||||
expr = build1 (NOP_EXPR, type, expr);
|
||||
expr = fold_convert (type, expr);
|
||||
if (integer_zerop (byte_diff))
|
||||
return expr;
|
||||
|
||||
|
@ -5267,6 +5267,21 @@ convert (tree type, tree expr)
|
|||
fold_convert (sizetype, byte_diff));
|
||||
}
|
||||
|
||||
/* If converting from a thin pointer with zero offset from the base to
|
||||
a pointer to the array, add the offset of the array field. */
|
||||
if (TYPE_IS_THIN_POINTER_P (etype)
|
||||
&& !TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (etype)))
|
||||
{
|
||||
tree arr_field = DECL_CHAIN (TYPE_FIELDS (TREE_TYPE (etype)));
|
||||
|
||||
if (TREE_TYPE (type) == TREE_TYPE (arr_field))
|
||||
{
|
||||
expr = fold_convert (type, expr);
|
||||
return build_binary_op (POINTER_PLUS_EXPR, type, expr,
|
||||
byte_position (arr_field));
|
||||
}
|
||||
}
|
||||
|
||||
/* If converting fat pointer to normal or thin pointer, get the pointer
|
||||
to the array and then convert it. */
|
||||
if (TYPE_IS_FAT_POINTER_P (etype))
|
||||
|
|
|
@ -1628,11 +1628,12 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand)
|
|||
= size_binop (PLUS_EXPR, offset,
|
||||
size_int (bits_to_bytes_round_down (bitpos)));
|
||||
|
||||
/* Take the address of INNER, convert it to a pointer to our type
|
||||
and add the offset. */
|
||||
inner = build_unary_op (ADDR_EXPR,
|
||||
build_pointer_type (TREE_TYPE (operand)),
|
||||
inner);
|
||||
/* Take the address of INNER, formally convert it to a pointer
|
||||
to the operand type, and finally add the offset. */
|
||||
inner = build_unary_op (ADDR_EXPR, NULL_TREE, inner);
|
||||
inner
|
||||
= fold_convert (build_pointer_type (TREE_TYPE (operand)),
|
||||
inner);
|
||||
result = build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (inner),
|
||||
inner, offset);
|
||||
break;
|
||||
|
|
Loading…
Add table
Reference in a new issue