Commit 3d529af4 by Robert Dewar Committed by Arnaud Charlet

sem_dim.adb: Minor error message change.

2013-07-08  Robert Dewar  <dewar@adacore.com>

	* sem_dim.adb: Minor error message change.
	* freeze.adb (Freeze_Entity, array type case): Extend handling
	of Implicit_Packing to handle multi-dimensional array case.
	* gnat_rm.texi: Update doc on Implicit_Packing.

From-SVN: r200762
parent 08daa782
2013-07-08 Robert Dewar <dewar@adacore.com> 2013-07-08 Robert Dewar <dewar@adacore.com>
* sem_dim.adb: Minor error message change.
* freeze.adb (Freeze_Entity, array type case): Extend handling
of Implicit_Packing to handle multi-dimensional array case.
* gnat_rm.texi: Update doc on Implicit_Packing.
2013-07-08 Robert Dewar <dewar@adacore.com>
* exp_ch4.adb: Minor reformatting. * exp_ch4.adb: Minor reformatting.
2013-07-08 Ed Schonberg <schonberg@adacore.com> 2013-07-08 Ed Schonberg <schonberg@adacore.com>
......
...@@ -3413,20 +3413,31 @@ package body Freeze is ...@@ -3413,20 +3413,31 @@ package body Freeze is
-- Before we do anything else, a specialized test for the case of -- Before we do anything else, a specialized test for the case of
-- a size given for an array where the array needs to be packed, -- a size given for an array where the array needs to be packed,
-- but was not so the size cannot be honored. This would of course -- but was not so the size cannot be honored. This is the case
-- be caught by the backend, and indeed we don't catch all cases. -- where implicit packing may apply. The reason we do this so
-- The point is that we can give a better error message in those -- early is that if we have implicit packing, the lagout of the
-- cases that we do catch with the circuitry here. Also if pragma -- base type is affected, so we must do this before we freeze
-- Implicit_Packing is set, this is where the packing occurs. -- the base type.
-- The reason we do this so early is that the processing in the -- We could do this processing only if implicit packing is enabled
-- automatic packing case affects the layout of the base type, so -- since in all other cases, the error would be caught by the back
-- it must be done before we freeze the base type. -- end. However, we choose to do the check even if we do not have
-- implicit packingh enabled, since this allows us to give a more
-- useful error message (advising the use of pack or the pragma).
if Is_Array_Type (E) then if Is_Array_Type (E) then
declare declare
Lo, Hi : Node_Id; Ctyp : constant Entity_Id := Component_Type (E);
Ctyp : constant Entity_Id := Component_Type (E); Rsiz : constant Uint := RM_Size (Ctyp);
SZ : constant Node_Id := Size_Clause (E);
Btyp : constant Entity_Id := Base_Type (E);
Lo : Node_Id;
Hi : Node_Id;
Indx : Node_Id;
Num_Elmts : Uint;
-- Number of elements in array
begin begin
-- Check enabling conditions. These are straightforward -- Check enabling conditions. These are straightforward
...@@ -3441,87 +3452,90 @@ package body Freeze is ...@@ -3441,87 +3452,90 @@ package body Freeze is
-- a chance to freeze the base type (and it is that freeze -- a chance to freeze the base type (and it is that freeze
-- action that causes stuff to be inherited). -- action that causes stuff to be inherited).
if Present (Size_Clause (E)) if Has_Size_Clause (E)
and then Known_Static_RM_Size (E) and then Known_Static_RM_Size (E)
and then not Is_Packed (E) and then not Is_Packed (E)
and then not Has_Pragma_Pack (E) and then not Has_Pragma_Pack (E)
and then Number_Dimensions (E) = 1
and then not Has_Component_Size_Clause (E) and then not Has_Component_Size_Clause (E)
and then Known_Static_RM_Size (Ctyp) and then Known_Static_RM_Size (Ctyp)
and then RM_Size (Ctyp) < 64
and then not Is_Limited_Composite (E) and then not Is_Limited_Composite (E)
and then not Is_Packed (Root_Type (E)) and then not Is_Packed (Root_Type (E))
and then not Has_Component_Size_Clause (Root_Type (E)) and then not Has_Component_Size_Clause (Root_Type (E))
and then not (CodePeer_Mode or SPARK_Mode) and then not (CodePeer_Mode or SPARK_Mode)
then then
Get_Index_Bounds (First_Index (E), Lo, Hi); -- Compute number of elements in array
if Compile_Time_Known_Value (Lo) Num_Elmts := Uint_1;
and then Compile_Time_Known_Value (Hi) Indx := First_Index (E);
and then Known_Static_RM_Size (Ctyp) while Present (Indx) loop
and then RM_Size (Ctyp) < 64 Get_Index_Bounds (Indx, Lo, Hi);
then
declare
Lov : constant Uint := Expr_Value (Lo);
Hiv : constant Uint := Expr_Value (Hi);
Len : constant Uint := UI_Max
(Uint_0,
Hiv - Lov + 1);
Rsiz : constant Uint := RM_Size (Ctyp);
SZ : constant Node_Id := Size_Clause (E);
Btyp : constant Entity_Id := Base_Type (E);
-- What we are looking for here is the situation where
-- the RM_Size given would be exactly right if there
-- was a pragma Pack (resulting in the component size
-- being the same as the RM_Size). Furthermore, the
-- component type size must be an odd size (not a
-- multiple of storage unit). If the component RM size
-- is an exact number of storage units that is a power
-- of two, the array is not packed and has a standard
-- representation.
begin if not (Compile_Time_Known_Value (Lo)
if RM_Size (E) = Len * Rsiz and then
and then Rsiz mod System_Storage_Unit /= 0 Compile_Time_Known_Value (Hi))
then then
-- For implicit packing mode, just set the goto No_Implicit_Packing;
-- component size silently. end if;
Num_Elmts :=
Num_Elmts *
UI_Max (Uint_0,
Expr_Value (Hi) - Expr_Value (Lo) + 1);
Next_Index (Indx);
end loop;
if Implicit_Packing then -- What we are looking for here is the situation where
Set_Component_Size (Btyp, Rsiz); -- the RM_Size given would be exactly right if there was
Set_Is_Bit_Packed_Array (Btyp); -- a pragma Pack (resulting in the component size being
Set_Is_Packed (Btyp); -- the same as the RM_Size). Furthermore, the component
Set_Has_Non_Standard_Rep (Btyp); -- type size must be an odd size (not a multiple of
-- storage unit). If the component RM size is an exact
-- number of storage units that is a power of two, the
-- array is not packed and has a standard representation.
if RM_Size (E) = Num_Elmts * Rsiz
and then Rsiz mod System_Storage_Unit /= 0
then
-- For implicit packing mode, just set the component
-- size silently.
-- Otherwise give an error message if Implicit_Packing then
Set_Component_Size (Btyp, Rsiz);
Set_Is_Bit_Packed_Array (Btyp);
Set_Is_Packed (Btyp);
Set_Has_Non_Standard_Rep (Btyp);
else -- Otherwise give an error message
Error_Msg_NE
("size given for& too small", SZ, E);
Error_Msg_N -- CODEFIX
("\use explicit pragma Pack "
& "or use pragma Implicit_Packing", SZ);
end if;
elsif RM_Size (E) = Len * Rsiz else
and then Implicit_Packing Error_Msg_NE
and then ("size given for& too small", SZ, E);
(Rsiz / System_Storage_Unit = 1 Error_Msg_N -- CODEFIX
or else Rsiz / System_Storage_Unit = 2 ("\use explicit pragma Pack "
or else Rsiz / System_Storage_Unit = 4) & "or use pragma Implicit_Packing", SZ);
then end if;
-- Not a packed array, but indicate the desired elsif RM_Size (E) = Num_Elmts * Rsiz
-- component size, for the back-end. and then Implicit_Packing
and then
(Rsiz / System_Storage_Unit = 1
or else
Rsiz / System_Storage_Unit = 2
or else
Rsiz / System_Storage_Unit = 4)
then
-- Not a packed array, but indicate the desired
-- component size, for the back-end.
Set_Component_Size (Btyp, Rsiz); Set_Component_Size (Btyp, Rsiz);
end if;
end;
end if; end if;
end if; end if;
end; end;
end if; end if;
<<No_Implicit_Packing>>
-- If ancestor subtype present, freeze that first. Note that this -- If ancestor subtype present, freeze that first. Note that this
-- will also get the base type frozen. Need RM reference ??? -- will also get the base type frozen. Need RM reference ???
......
...@@ -3255,8 +3255,10 @@ of the configuration pragma Implicit_Packing, then the Size clause in this ...@@ -3255,8 +3255,10 @@ of the configuration pragma Implicit_Packing, then the Size clause in this
and similar examples will cause implicit packing and thus be accepted. For and similar examples will cause implicit packing and thus be accepted. For
this implicit packing to occur, the type in question must be an array of small this implicit packing to occur, the type in question must be an array of small
components whose size is known at compile time, and the Size clause must components whose size is known at compile time, and the Size clause must
specify the exact size that corresponds to the length of the array multiplied specify the exact size that corresponds to the number of elements in the array
by the size in bits of the component type. multiplied by the size in bits of the component type (both single and
multi-dimensioned arrays can be controlled with this pragma).
@cindex Array packing @cindex Array packing
Similarly, the following example shows the use in the record case Similarly, the following example shows the use in the record case
......
...@@ -1409,7 +1409,7 @@ package body Sem_Dim is ...@@ -1409,7 +1409,7 @@ package body Sem_Dim is
if L_Has_Dimensions then if L_Has_Dimensions then
if not Compile_Time_Known_Value (R) then if not Compile_Time_Known_Value (R) then
Error_Msg_N ("exponent of dimensioned operand must be " & Error_Msg_N ("exponent of dimensioned operand must be " &
"known at compile-time", N); "known at compile time", N);
end if; end if;
declare declare
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment