From f91caacb455ba93610b3cb751d88d36aa58b3a58 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 16 May 2016 11:20:45 +0000 Subject: [PATCH] freeze.adb (Freeze_Record_Type): Extend pragma Implicit_Packing to components of any elementary types and of... * freeze.adb (Freeze_Record_Type): Extend pragma Implicit_Packing to components of any elementary types and of composite types. From-SVN: r236282 --- gcc/ada/ChangeLog | 5 ++++ gcc/ada/freeze.adb | 64 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index ca337e7bf32..246c7703490 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2016-05-16 Eric Botcazou + + * freeze.adb (Freeze_Record_Type): Extend pragma Implicit_Packing to + components of any elementary types and of composite types. + 2016-05-16 Eric Botcazou * freeze.adb (Freeze_Array_Type): Call Addressable predicate instead diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb index 2a021e25cf1..ec8ea2c3a4e 100644 --- a/gcc/ada/freeze.adb +++ b/gcc/ada/freeze.adb @@ -3534,13 +3534,23 @@ package body Freeze is -- Set True if we find at least one component whose type has a -- Scalar_Storage_Order attribute definition clause. - All_Scalar_Components : Boolean := True; - -- Set False if we encounter a component of a non-scalar type + All_Elem_Components : Boolean := True; + -- Set False if we encounter a component of a composite type - Scalar_Component_Total_RM_Size : Uint := Uint_0; - Scalar_Component_Total_Esize : Uint := Uint_0; - -- Accumulates total RM_Size values and total Esize values of all - -- scalar components. Used for processing of Implicit_Packing. + All_Sized_Components : Boolean := True; + -- Set False if we encounter a component with unknown RM_Size + + All_Storage_Unit_Components : Boolean := True; + -- Set False if we encounter a component of a composite type whose + -- RM_Size is not a multiple of the storage unit. + + Elem_Component_Total_Esize : Uint := Uint_0; + -- Accumulates total Esize values of all elementary components. Used + -- for processing of Implicit_Packing. + + Sized_Component_Total_RM_Size : Uint := Uint_0; + -- Accumulates total RM_Size values of all sized components. Used + -- for processing of Implicit_Packing. function Check_Allocator (N : Node_Id) return Node_Id; -- If N is an allocator, possibly wrapped in one or more level of @@ -3835,13 +3845,22 @@ package body Freeze is -- this stage we might be dealing with a real component, or with -- an implicit subtype declaration. - if not Is_Scalar_Type (Etype (Comp)) then - All_Scalar_Components := False; + if Known_Static_RM_Size (Etype (Comp)) then + Sized_Component_Total_RM_Size := + Sized_Component_Total_RM_Size + RM_Size (Etype (Comp)); + + if Is_Elementary_Type (Etype (Comp)) then + Elem_Component_Total_Esize := + Elem_Component_Total_Esize + Esize (Etype (Comp)); + else + All_Elem_Components := False; + + if RM_Size (Etype (Comp)) mod System_Storage_Unit /= 0 then + All_Storage_Unit_Components := False; + end if; + end if; else - Scalar_Component_Total_RM_Size := - Scalar_Component_Total_RM_Size + RM_Size (Etype (Comp)); - Scalar_Component_Total_Esize := - Scalar_Component_Total_Esize + Esize (Etype (Comp)); + All_Sized_Components := False; end if; -- If the component is an Itype with Delayed_Freeze and is either @@ -4312,26 +4331,33 @@ package body Freeze is and then not Aliased_Component - -- Must have size clause and all scalar components + -- Must have size clause and all sized components and then Has_Size_Clause (Rec) - and then All_Scalar_Components + and then All_Sized_Components -- Do not try implicit packing on records with discriminants, too -- complicated, especially in the variant record case. and then not Has_Discriminants (Rec) - -- We can implicitly pack if the specified size of the record is - -- less than the sum of the object sizes (no point in packing if - -- this is not the case). + -- We want to implicitly pack if the specified size of the record + -- is less than the sum of the object sizes (no point in packing + -- if this is not the case) if we can compute it, i.e. if we have + -- only elementary components. Otherwise, we have at least one + -- composite component and we want to implicit pack only if bit + -- packing is required for it, as we are sure in this case that + -- the back end cannot do the expected layout without packing. - and then RM_Size (Rec) < Scalar_Component_Total_Esize + and then ((All_Elem_Components + and then RM_Size (Rec) < Elem_Component_Total_Esize) + or else (not All_Elem_Components + and then not All_Storage_Unit_Components)) -- And the total RM size cannot be greater than the specified size -- since otherwise packing will not get us where we have to be. - and then RM_Size (Rec) >= Scalar_Component_Total_RM_Size + and then RM_Size (Rec) >= Sized_Component_Total_RM_Size -- Never do implicit packing in CodePeer or SPARK modes since -- we don't do any packing in these modes, since this generates -- 2.30.2