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
This commit is contained in:
Eric Botcazou 2013-12-04 11:27:25 +00:00 committed by Eric Botcazou
parent 5bf51f2f73
commit 6bc8df2439
4 changed files with 88 additions and 0 deletions

View File

@ -1,3 +1,8 @@
2013-12-04 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (components_to_record): Add specific handling
for fields with zero size and no representation clause.
2013-12-04 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/trans.c (Case_Statement_to_gnu): Do not push a binding

View File

@ -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;
}

View File

@ -1,3 +1,7 @@
2013-12-04 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/pack19.adb: New test.
2013-12-04 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/58726

View File

@ -0,0 +1,56 @@
-- { dg-do run }
procedure Pack19 is
subtype Always_False is Boolean range False .. False;
type Rec1 is record
B1 : Boolean;
B2 : Boolean;
B3 : Boolean;
B4 : Boolean;
B5 : Boolean;
B6 : Boolean;
B7 : Always_False;
B8 : Boolean;
end record;
pragma Pack (Rec1);
subtype Always_True is Boolean range True .. True;
type Rec2 is record
B1 : Boolean;
B2 : Boolean;
B3 : Boolean;
B4 : Boolean;
B5 : Boolean;
B6 : Boolean;
B7 : Always_True;
B8 : Boolean;
end record;
pragma Pack (Rec2);
R1 : Rec1 := (True, True, True, True, True, True, False, False);
R2 : Rec2 := (False, False, False, False, False, False, True, True);
begin
R1.B8 := True;
if R1.B7 /= False then
raise Program_Error;
end if;
R1.B7 := False;
if R1.B7 /= False then
raise Program_Error;
end if;
R2.B8 := False;
if R2.B7 /= True then
raise Program_Error;
end if;
R2.B7 := True;
if R2.B7 /= True then
raise Program_Error;
end if;
end;