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;
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,
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
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