diff options
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 43 |
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 |