diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2019-08-30 15:12:20 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2019-08-30 15:12:20 +0000 |
commit | 0c2837b5c408f8fd2b023a7bf00be9abd1e28a28 (patch) | |
tree | 706ae520a2d14fa4f31a700f4138b4b994367b57 /gcc/ada/gcc-interface/utils.c | |
parent | c85dbadc061f7c7f3575e335976150370d8652be (diff) | |
download | gcc-0c2837b5c408f8fd2b023a7bf00be9abd1e28a28.zip gcc-0c2837b5c408f8fd2b023a7bf00be9abd1e28a28.tar.gz gcc-0c2837b5c408f8fd2b023a7bf00be9abd1e28a28.tar.bz2 |
gigi.h (aggregate_type_contains_array_p): Declare.
* gcc-interface/gigi.h (aggregate_type_contains_array_p): Declare.
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Type>: For an
extension, test Has_Record_Rep_Clause instead of Has_Specified_Layout.
(adjust_packed): Return 0 if the type of the field is an aggregate
type that contains (or is) a self-referential array.
(type_has_variable_size): Delete.
* gcc-interface/utils.c (inish_record_type): Constify a variable.
(aggregate_type_contains_array_p): Add parameter SELF_REFERENTIAL.
<RECORD_TYPE>: Pass it in the recursive call.
<ARRAY_TYPE>: If it is true, return true only if the array type is
self-referential.
(create_field_decl): Streamline the setting of the alignment on the
field. Pass false to aggregate_type_contains_array_p.
From-SVN: r275196
Diffstat (limited to 'gcc/ada/gcc-interface/utils.c')
-rw-r--r-- | gcc/ada/gcc-interface/utils.c | 69 |
1 files changed, 38 insertions, 31 deletions
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 0202576..8a38b34 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -1948,7 +1948,7 @@ finish_record_type (tree record_type, tree field_list, int rep_level, if (DECL_BIT_FIELD (field) && operand_equal_p (this_size, TYPE_SIZE (type), 0)) { - unsigned int align = TYPE_ALIGN (type); + const unsigned int align = TYPE_ALIGN (type); /* In the general case, type alignment is required. */ if (value_factor_p (pos, align)) @@ -2764,10 +2764,12 @@ create_var_decl (tree name, tree asm_name, tree type, tree init, return var_decl; } -/* Return true if TYPE, an aggregate type, contains (or is) an array. */ +/* Return true if TYPE, an aggregate type, contains (or is) an array. + If SELF_REFERENTIAL is true, then an additional requirement on the + array is that it be self-referential. */ -static bool -aggregate_type_contains_array_p (tree type) +bool +aggregate_type_contains_array_p (tree type, bool self_referential) { switch (TREE_CODE (type)) { @@ -2778,13 +2780,14 @@ aggregate_type_contains_array_p (tree type) tree field; for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) if (AGGREGATE_TYPE_P (TREE_TYPE (field)) - && aggregate_type_contains_array_p (TREE_TYPE (field))) + && aggregate_type_contains_array_p (TREE_TYPE (field), + self_referential)) return true; return false; } case ARRAY_TYPE: - return true; + return self_referential ? type_contains_placeholder_p (type) : true; default: gcc_unreachable (); @@ -2808,18 +2811,6 @@ create_field_decl (tree name, tree type, tree record_type, tree size, tree pos, DECL_CONTEXT (field_decl) = record_type; TREE_READONLY (field_decl) = TYPE_READONLY (type); - /* If FIELD_TYPE is BLKmode, we must ensure this is aligned to at least a - byte boundary since GCC cannot handle less-aligned BLKmode bitfields. - Likewise for an aggregate without specified position that contains an - array, because in this case slices of variable length of this array - must be handled by GCC and variable-sized objects need to be aligned - to at least a byte boundary. */ - if (packed && (TYPE_MODE (type) == BLKmode - || (!pos - && AGGREGATE_TYPE_P (type) - && aggregate_type_contains_array_p (type)))) - SET_DECL_ALIGN (field_decl, BITS_PER_UNIT); - /* If a size is specified, use it. Otherwise, if the record type is packed compute a size to use, which may differ from the object's natural size. We always set a size in this case to trigger the checks for bitfield @@ -2872,23 +2863,39 @@ create_field_decl (tree name, tree type, tree record_type, tree size, tree pos, DECL_PACKED (field_decl) = pos ? DECL_BIT_FIELD (field_decl) : packed; + /* If FIELD_TYPE is BLKmode, we must ensure this is aligned to at least a + byte boundary since GCC cannot handle less-aligned BLKmode bitfields. + Likewise for an aggregate without specified position that contains an + array, because in this case slices of variable length of this array + must be handled by GCC and variable-sized objects need to be aligned + to at least a byte boundary. */ + if (packed && (TYPE_MODE (type) == BLKmode + || (!pos + && AGGREGATE_TYPE_P (type) + && aggregate_type_contains_array_p (type, false)))) + SET_DECL_ALIGN (field_decl, BITS_PER_UNIT); + /* Bump the alignment if need be, either for bitfield/packing purposes or - to satisfy the type requirements if no such consideration applies. When + to satisfy the type requirements if no such considerations apply. When we get the alignment from the type, indicate if this is from an explicit user request, which prevents stor-layout from lowering it later on. */ - { - unsigned int bit_align - = (DECL_BIT_FIELD (field_decl) ? 1 - : packed && TYPE_MODE (type) != BLKmode ? BITS_PER_UNIT : 0); + else + { + const unsigned int field_align + = DECL_BIT_FIELD (field_decl) + ? 1 + : packed + ? BITS_PER_UNIT + : 0; - if (bit_align > DECL_ALIGN (field_decl)) - SET_DECL_ALIGN (field_decl, bit_align); - else if (!bit_align && TYPE_ALIGN (type) > DECL_ALIGN (field_decl)) - { - SET_DECL_ALIGN (field_decl, TYPE_ALIGN (type)); - DECL_USER_ALIGN (field_decl) = TYPE_USER_ALIGN (type); - } - } + if (field_align > DECL_ALIGN (field_decl)) + SET_DECL_ALIGN (field_decl, field_align); + else if (!field_align && TYPE_ALIGN (type) > DECL_ALIGN (field_decl)) + { + SET_DECL_ALIGN (field_decl, TYPE_ALIGN (type)); + DECL_USER_ALIGN (field_decl) = TYPE_USER_ALIGN (type); + } + } if (pos) { |