diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2013-12-04 11:27:25 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2013-12-04 11:27:25 +0000 |
commit | 6bc8df24390d66b92a2b23d31f010911f13c6c40 (patch) | |
tree | 30f5199f3153bae7b0afb229d388990a213905df /gcc/ada/gcc-interface/decl.c | |
parent | 5bf51f2f731c28ea9b45e170fc36a2b0d51ba9b2 (diff) | |
download | gcc-6bc8df24390d66b92a2b23d31f010911f13c6c40.zip gcc-6bc8df24390d66b92a2b23d31f010911f13c6c40.tar.gz gcc-6bc8df24390d66b92a2b23d31f010911f13c6c40.tar.bz2 |
decl.c (components_to_record): Add specific handling for fields with zero size and no representation clause.
* gcc-interface/decl.c (components_to_record): Add specific handling
for fields with zero size and no representation clause.
From-SVN: r205665
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index ee76a9d..a80d1a9 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -6932,6 +6932,7 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list, tree gnu_rep_list = NULL_TREE; tree gnu_var_list = NULL_TREE; tree gnu_self_list = NULL_TREE; + tree gnu_zero_list = NULL_TREE; /* For each component referenced in a component declaration create a GCC field and add it to the list, skipping pragmas in the GNAT list. */ @@ -7262,6 +7263,10 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list, to do this in a separate pass since we want to handle the discriminants but can't play with them until we've used them in debugging data above. + Similarly, pull out the fields with zero size and no rep clause, as they + would otherwise modify the layout and thus very likely run afoul of the + Ada semantics, which are different from those of C here. + ??? If we reorder them, debugging information will be wrong but there is nothing that can be done about this at the moment. */ gnu_last = NULL_TREE; @@ -7300,6 +7305,19 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list, continue; } + if (DECL_SIZE (gnu_field) && integer_zerop (DECL_SIZE (gnu_field))) + { + DECL_FIELD_OFFSET (gnu_field) = size_zero_node; + SET_DECL_OFFSET_ALIGN (gnu_field, BIGGEST_ALIGNMENT); + DECL_FIELD_BIT_OFFSET (gnu_field) = bitsize_zero_node; + if (field_is_aliased (gnu_field)) + TYPE_ALIGN (gnu_record_type) + = MAX (TYPE_ALIGN (gnu_record_type), + TYPE_ALIGN (TREE_TYPE (gnu_field))); + MOVE_FROM_FIELD_LIST_TO (gnu_zero_list); + continue; + } + gnu_last = gnu_field; } @@ -7392,6 +7410,11 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list, finish_record_type (gnu_record_type, gnu_field_list, layout_with_rep ? 1 : 0, debug_info && !maybe_unused); + /* Chain the fields with zero size at the beginning of the field list. */ + if (gnu_zero_list) + TYPE_FIELDS (gnu_record_type) + = chainon (gnu_zero_list, TYPE_FIELDS (gnu_record_type)); + return (gnu_rep_list && !p_gnu_rep_list) || variants_have_rep; } |