aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r--gcc/ada/gcc-interface/decl.c82
1 files changed, 38 insertions, 44 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 3ae079f..2450b50 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -2829,11 +2829,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
? 1
: Component_Alignment (gnat_entity) == Calign_Storage_Unit
? -1
- : (Known_Alignment (gnat_entity)
- || (Strict_Alignment (gnat_entity)
- && Known_RM_Size (gnat_entity)))
- ? -2
- : 0;
+ : 0;
+ const bool has_align = Known_Alignment (gnat_entity);
const bool has_discr = Has_Discriminants (gnat_entity);
const bool has_rep = Has_Specified_Layout (gnat_entity);
const bool is_extension
@@ -2872,7 +2869,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
suppress expanding incomplete types. */
gnu_type = make_node (tree_code_for_record_type (gnat_entity));
TYPE_NAME (gnu_type) = gnu_entity_name;
- TYPE_PACKED (gnu_type) = (packed != 0) || has_rep;
+ TYPE_PACKED (gnu_type) = (packed != 0) || has_align || has_rep;
TYPE_REVERSE_STORAGE_ORDER (gnu_type)
= Reverse_Storage_Order (gnat_entity);
process_attributes (&gnu_type, &attr_list, true, gnat_entity);
@@ -2883,38 +2880,32 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
this_deferred = true;
}
- /* If both a size and rep clause was specified, put the size in
- the record type now so that it can get the proper mode. */
+ /* If both a size and rep clause were specified, put the size on
+ the record type now so that it can get the proper layout. */
if (has_rep && Known_RM_Size (gnat_entity))
TYPE_SIZE (gnu_type)
= UI_To_gnu (RM_Size (gnat_entity), bitsizetype);
- /* Always set the alignment here so that it can be used to
- set the mode, if it is making the alignment stricter. If
- it is invalid, it will be checked again below. If this is to
- be Atomic, choose a default alignment of a word unless we know
- the size and it's smaller. */
- if (Known_Alignment (gnat_entity))
+ /* Always set the alignment on the record type here so that it can
+ get the proper layout. */
+ if (has_align)
TYPE_ALIGN (gnu_type)
= validate_alignment (Alignment (gnat_entity), gnat_entity, 0);
- else if (Is_Atomic_Or_VFA (gnat_entity) && Known_Esize (gnat_entity))
- {
- unsigned int size = UI_To_Int (Esize (gnat_entity));
- TYPE_ALIGN (gnu_type)
- = size >= BITS_PER_WORD ? BITS_PER_WORD : ceil_pow2 (size);
- }
- /* If a type needs strict alignment, the minimum size will be the
- type size instead of the RM size (see validate_size). Cap the
- alignment, lest it causes this type size to become too large. */
- else if (Strict_Alignment (gnat_entity) && Known_RM_Size (gnat_entity))
+ else
{
- unsigned int raw_size = UI_To_Int (RM_Size (gnat_entity));
- unsigned int raw_align = raw_size & -raw_size;
- if (raw_align < BIGGEST_ALIGNMENT)
- TYPE_ALIGN (gnu_type) = raw_align;
+ TYPE_ALIGN (gnu_type) = 0;
+
+ /* If a type needs strict alignment, the minimum size will be the
+ type size instead of the RM size (see validate_size). Cap the
+ alignment lest it causes this type size to become too large. */
+ if (Strict_Alignment (gnat_entity) && Known_RM_Size (gnat_entity))
+ {
+ unsigned int max_size = UI_To_Int (RM_Size (gnat_entity));
+ unsigned int max_align = max_size & -max_size;
+ if (max_align < BIGGEST_ALIGNMENT)
+ TYPE_MAX_ALIGN (gnu_type) = max_align;
+ }
}
- else
- TYPE_ALIGN (gnu_type) = 0;
/* If we have a Parent_Subtype, make a field for the parent. If
this record has rep clauses, force the position to zero. */
@@ -6502,25 +6493,29 @@ adjust_packed (tree field_type, tree record_type, int packed)
if (type_has_variable_size (field_type))
return 0;
+ /* In the other cases, we can honor the packing. */
+ if (packed)
+ return packed;
+
/* If the alignment of the record is specified and the field type
is over-aligned, request Storage_Unit alignment for the field. */
- if (packed == -2)
- {
- if (TYPE_ALIGN (field_type) > TYPE_ALIGN (record_type))
- return -1;
- else
- return 0;
- }
+ if (TYPE_ALIGN (record_type)
+ && TYPE_ALIGN (field_type) > TYPE_ALIGN (record_type))
+ return -1;
+
+ /* Likewise if the maximum alignment of the record is specified. */
+ if (TYPE_MAX_ALIGN (record_type)
+ && TYPE_ALIGN (field_type) > TYPE_MAX_ALIGN (record_type))
+ return -1;
- return packed;
+ return 0;
}
/* Return a GCC tree for a field corresponding to GNAT_FIELD to be
placed in GNU_RECORD_TYPE.
- PACKED is 1 if the enclosing record is packed, -1 if the enclosing
- record has Component_Alignment of Storage_Unit, -2 if the enclosing
- record has a specified alignment.
+ PACKED is 1 if the enclosing record is packed or -1 if the enclosing
+ record has Component_Alignment of Storage_Unit.
DEFINITION is true if this field is for a record being defined.
@@ -6989,9 +6984,8 @@ typedef struct vinfo
GNU_FIELD_LIST. The other calls to this function are recursive calls for
the component list of a variant and, in this case, GNU_FIELD_LIST is empty.
- PACKED is 1 if this is for a packed record, -1 if this is for a record
- with Component_Alignment of Storage_Unit, -2 if this is for a record
- with a specified alignment.
+ PACKED is 1 if this is for a packed record or -1 if this is for a record
+ with Component_Alignment of Storage_Unit.
DEFINITION is true if we are defining this record type.