[COMMITTED] ada: Fix issue with indefinite vector of overaligned unconstrained array
Checks
Commit Message
From: Eric Botcazou <ebotcazou@adacore.com>
The problem is that the aligning machinery is not consistently triggered,
depending on whether a constrained view or the nominal unconstrained view
of the element type is used to perform the allocations and deallocations.
gcc/ada/
* gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Array_Subtype>: Put
the alignment directly on the type in the constrained case too.
* gcc-interface/utils.cc (maybe_pad_type): For an array type, take
the alignment of the element type as the original alignment.
Tested on x86_64-pc-linux-gnu, committed on master.
---
gcc/ada/gcc-interface/decl.cc | 12 ++++++++++++
gcc/ada/gcc-interface/utils.cc | 19 ++++++++++++++++---
2 files changed, 28 insertions(+), 3 deletions(-)
@@ -3010,6 +3010,18 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
TREE_TYPE (TYPE_FIELDS (gnu_type)) = gnu_inner;
}
}
+
+ /* Otherwise, if an alignment is specified, use it if valid and, if
+ the alignment was requested with an explicit clause, state so. */
+ else if (Known_Alignment (gnat_entity))
+ {
+ SET_TYPE_ALIGN (gnu_type,
+ validate_alignment (Alignment (gnat_entity),
+ gnat_entity,
+ TYPE_ALIGN (gnu_type)));
+ if (Present (Alignment_Clause (gnat_entity)))
+ TYPE_USER_ALIGN (gnu_type) = 1;
+ }
}
break;
@@ -1485,7 +1485,14 @@ canonicalize_pad_type (tree type)
IS_COMPONENT_TYPE is true if this is being done for the component type of
an array. DEFINITION is true if this type is being defined. SET_RM_SIZE
is true if the RM size of the resulting type is to be set to SIZE too; in
- this case, the padded type is canonicalized before being returned. */
+ this case, the padded type is canonicalized before being returned.
+
+ Note that, if TYPE is an array, then we pad it even if it has already got
+ an alignment of ALIGN, provided that it's larger than the alignment of the
+ element type. This ensures that the size of the type is a multiple of its
+ alignment as required by the GCC type system, and alleviates the oddity of
+ the larger alignment, which is used to implement alignment clauses present
+ on unconstrained array types. */
tree
maybe_pad_type (tree type, tree size, unsigned int align,
@@ -1493,7 +1500,10 @@ maybe_pad_type (tree type, tree size, unsigned int align,
bool definition, bool set_rm_size)
{
tree orig_size = TYPE_SIZE (type);
- unsigned int orig_align = TYPE_ALIGN (type);
+ unsigned int orig_align
+ = TREE_CODE (type) == ARRAY_TYPE
+ ? TYPE_ALIGN (TREE_TYPE (type))
+ : TYPE_ALIGN (type);
tree record, field;
/* If TYPE is a padded type, see if it agrees with any size and alignment
@@ -1515,7 +1525,10 @@ maybe_pad_type (tree type, tree size, unsigned int align,
type = TREE_TYPE (TYPE_FIELDS (type));
orig_size = TYPE_SIZE (type);
- orig_align = TYPE_ALIGN (type);
+ orig_align
+ = TREE_CODE (type) == ARRAY_TYPE
+ ? TYPE_ALIGN (TREE_TYPE (type))
+ : TYPE_ALIGN (type);
}
/* If the size is either not being changed or is being made smaller (which