aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/decl.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2019-08-30 15:12:20 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2019-08-30 15:12:20 +0000
commit0c2837b5c408f8fd2b023a7bf00be9abd1e28a28 (patch)
tree706ae520a2d14fa4f31a700f4138b4b994367b57 /gcc/ada/gcc-interface/decl.c
parentc85dbadc061f7c7f3575e335976150370d8652be (diff)
downloadgcc-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/decl.c')
-rw-r--r--gcc/ada/gcc-interface/decl.c43
1 files changed, 11 insertions, 32 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 0695c2f..5fce2ad 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -202,7 +202,6 @@ static void prepend_one_attribute_pragma (struct attrib **, Node_Id);
static void prepend_attributes (struct attrib **, Entity_Id);
static tree elaborate_expression (Node_Id, Entity_Id, const char *, bool, bool,
bool);
-static bool type_has_variable_size (tree);
static tree elaborate_expression_1 (tree, Entity_Id, const char *, bool, bool);
static tree elaborate_expression_2 (tree, Entity_Id, const char *, bool, bool,
unsigned int);
@@ -2953,10 +2952,13 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
: 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
= (Is_Tagged_Type (gnat_entity)
&& Nkind (record_definition) == N_Derived_Type_Definition);
+ const bool has_rep
+ = is_extension
+ ? Has_Record_Rep_Clause (gnat_entity)
+ : Has_Specified_Layout (gnat_entity);
const bool is_unchecked_union = Is_Unchecked_Union (gnat_entity);
bool all_rep = has_rep;
@@ -6865,11 +6867,13 @@ choices_to_gnu (tree gnu_operand, Node_Id gnat_choices)
static int
adjust_packed (tree field_type, tree record_type, int packed)
{
- /* If the field contains an item of variable size, we cannot pack it
- because we cannot create temporaries of non-fixed size in case
- we need to take the address of the field. See addressable_p and
- the notes on the addressability issues for further details. */
- if (type_has_variable_size (field_type))
+ /* If the field contains an array with self-referential size, we'd better
+ not pack it because this would misalign it and, therefore, cause large
+ temporaries to be created in case we need to take the address of the
+ field. See addressable_p and the notes on the addressability issues
+ for further details. */
+ if (AGGREGATE_TYPE_P (field_type)
+ && aggregate_type_contains_array_p (field_type, true))
return 0;
/* In the other cases, we can honor the packing. */
@@ -7274,31 +7278,6 @@ components_need_strict_alignment (Node_Id component_list)
return false;
}
-/* Return true if TYPE is a type with variable size or a padding type with a
- field of variable size or a record that has a field with such a type. */
-
-static bool
-type_has_variable_size (tree type)
-{
- tree field;
-
- if (!TREE_CONSTANT (TYPE_SIZE (type)))
- return true;
-
- if (TYPE_IS_PADDING_P (type)
- && !TREE_CONSTANT (DECL_SIZE (TYPE_FIELDS (type))))
- return true;
-
- if (!RECORD_OR_UNION_TYPE_P (type))
- return false;
-
- for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
- if (type_has_variable_size (TREE_TYPE (field)))
- return true;
-
- return false;
-}
-
/* Return true if FIELD is an artificial field. */
static bool