decl.c (components_need_strict_alignment): New.

* gcc-interface/decl.c (components_need_strict_alignment): New.
	(components_to_record): Do not pack the variants if one of the fields
	needs strict alignment.  Likewise for the variant part as a whole.
	Specify the position of the variants even if the size isn't specified,
	but do not specify the size of the variant part in this case.

From-SVN: r193750
This commit is contained in:
Eric Botcazou 2012-11-23 10:42:50 +00:00
parent 1076781c1f
commit 29e100b31a
4 changed files with 80 additions and 9 deletions

View file

@ -1,8 +1,15 @@
2012-11-23 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (components_need_strict_alignment): New.
(components_to_record): Do not pack the variants if one of the fields
needs strict alignment. Likewise for the variant part as a whole.
Specify the position of the variants even if the size isn't specified,
but do not specify the size of the variant part in this case.
2012-11-20 Diego Novillo <dnovillo@google.com>
Jakub Jelinek <jakub@redhat.com>
* gcc-interface/decl.c: Replace all vec<T,A>()
initializers with vNULL.
* gcc-interface/decl.c: Replace all vec<T,A>() initializers with vNULL.
2012-11-18 Eric Botcazou <ebotcazou@adacore.com>

View file

@ -6650,6 +6650,30 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
return gnu_field;
}
/* Return true if at least one member of COMPONENT_LIST needs strict
alignment. */
static bool
components_need_strict_alignment (Node_Id component_list)
{
Node_Id component_decl;
for (component_decl = First_Non_Pragma (Component_Items (component_list));
Present (component_decl);
component_decl = Next_Non_Pragma (component_decl))
{
Entity_Id gnat_field = Defining_Entity (component_decl);
if (Is_Aliased (gnat_field))
return True;
if (Strict_Alignment (Etype (gnat_field)))
return True;
}
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. */
@ -6880,6 +6904,7 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list,
"XVN");
tree gnu_union_type, gnu_union_name;
tree this_first_free_pos, gnu_variant_list = NULL_TREE;
bool union_field_needs_strict_alignment = false;
if (TREE_CODE (gnu_name) == TYPE_DECL)
gnu_name = DECL_NAME (gnu_name);
@ -6980,8 +7005,18 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list,
else
{
/* Deal with packedness like in gnat_to_gnu_field. */
int field_packed
= adjust_packed (gnu_variant_type, gnu_record_type, packed);
bool field_needs_strict_alignment
= components_need_strict_alignment (Component_List (variant));
int field_packed;
if (field_needs_strict_alignment)
{
field_packed = 0;
union_field_needs_strict_alignment = true;
}
else
field_packed
= adjust_packed (gnu_variant_type, gnu_record_type, packed);
/* Finalize the record type now. We used to throw away
empty records but we no longer do that because we need
@ -6997,8 +7032,7 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list,
gnu_union_type,
all_rep_and_size
? TYPE_SIZE (gnu_variant_type) : 0,
all_rep_and_size
? bitsize_zero_node : 0,
all_rep ? bitsize_zero_node : 0,
field_packed, 0);
DECL_INTERNAL_P (gnu_field) = 1;
@ -7041,12 +7075,16 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list,
NULL, true, debug_info, gnat_component_list);
/* Deal with packedness like in gnat_to_gnu_field. */
union_field_packed
= adjust_packed (gnu_union_type, gnu_record_type, packed);
if (union_field_needs_strict_alignment)
union_field_packed = 0;
else
union_field_packed
= adjust_packed (gnu_union_type, gnu_record_type, packed);
gnu_variant_part
= create_field_decl (gnu_var_name, gnu_union_type, gnu_record_type,
all_rep ? TYPE_SIZE (gnu_union_type) : 0,
all_rep_and_size
? TYPE_SIZE (gnu_union_type) : 0,
all_rep || this_first_free_pos
? bitsize_zero_node : 0,
union_field_packed, 0);

View file

@ -1,3 +1,7 @@
2012-11-23 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/discr39.adb: New test.
2012-11-23 Georg-Johann Lay <avr@gjlay.de>
PR testsuite/52641

View file

@ -0,0 +1,22 @@
-- { dg-do run }
with System.Storage_Elements; use System.Storage_Elements;
procedure Discr39 is
type Rec (Has_Src : Boolean) is record
case Has_Src is
when True => Src : aliased Integer;
when False => null;
end case;
end record;
pragma Pack(Rec);
for Rec'Alignment use Integer'Alignment;
R : Rec (Has_Src => True);
begin
if R.Src'Address mod Integer'Alignment /= 0 then
raise Program_Error;
end if;
end;