]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada: Allow implicit packing of arrays when larger than needed
authorBob Duff <duff@adacore.com>
Sun, 17 Aug 2025 15:23:23 +0000 (11:23 -0400)
committerMarc Poulhiès <dkm@gcc.gnu.org>
Thu, 11 Sep 2025 09:10:47 +0000 (11:10 +0200)
For Implicit_Packing, do not require the Size clause to exactly match
the packed size.

For example, an array of 7 Booleans will fit in
7 bits if packed, or 7*8=56 bits if not packed.
This patch allows "for T'Size use 8;" to force packing
in Implicit_Packing mode; previously, the compiler
ignored Implicit_Packing unless it was exactly "use 7".

Apparently, customers have that sort of code, and the
whole point of Implicit_Packing is to allow such legacy
code to work.

We already do the right thing for records, at least in
cases tested.

We deliberately avoid changing the error messages given here.
They could possibly use some work, but there are subtle interactions
with the messages given in Sem_Ch13 for the same thing.

gcc/ada/ChangeLog:

* freeze.adb (Freeze_Entity): Change "=" to ">=" in
size comparison for Implicit_Packing mode.
Keep it as "=" for giving error messages.
* opt.ads (Implicit_Packing): Minor: correct obsolete
comment.

gcc/ada/freeze.adb
gcc/ada/opt.ads

index 8fa25b3d851047ede280fcc5ebafb010105b7bc0..1bbc24f62fe24347c1bd331d5204e46d89c989b4 100644 (file)
@@ -7151,31 +7151,30 @@ package body Freeze is
                         Next_Index (Indx);
                      end loop;
 
-                     --  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 RM_Size of the component type.
+                     --  In Implicit_Packing mode, if the specified RM_Size
+                     --  would be big enough if there were a pragma Pack,
+                     --  then set the component size as if there were Pack,
+                     --  and Freeze_Array_Type will do the rest.
 
-                     if RM_Size (E) = Num_Elmts * Rsiz then
-
-                        --  For implicit packing mode, just set the component
-                        --  size and Freeze_Array_Type will do the rest.
-
-                        if Implicit_Packing then
-                           Set_Component_Size (Btyp, Rsiz);
+                     if Implicit_Packing
+                       and then RM_Size (E) >= Num_Elmts * Rsiz
+                     then
+                        Set_Component_Size (Btyp, Rsiz);
 
-                        --  Otherwise give an error message, except that if the
-                        --  specified Size is zero, there is no need for pragma
-                        --  Pack. Note that size zero is not considered
-                        --  Addressable.
+                     --  Otherwise, if pragma Pack would result in exactly the
+                     --  right size, give an error message suggesting packing,
+                     --  except that if the specified Size is zero, there is no
+                     --  need for pragma Pack. Note that size zero is not
+                     --  considered Addressable.
 
-                        elsif RM_Size (E) /= Uint_0 then
-                           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) = Num_Elmts * Rsiz
+                       and then RM_Size (E) /= Uint_0
+                     then
+                        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;
                   end if;
                end;
index 524a823bb8f6c660b61d8e0ac99e5ba908f49907..109d28245de91f1f5aa2163a8d24777cdc436ff5 100644 (file)
@@ -835,9 +835,9 @@ package Opt is
 
    Implicit_Packing : Boolean := False;
    --  GNAT
-   --  If set True, then a Size attribute clause on an array is allowed to
-   --  cause implicit packing instead of generating an error message. Set by
-   --  use of pragma Implicit_Packing.
+   --  If set True, then a Size attribute clause on an array or record is
+   --  allowed to cause implicit packing instead of generating an error
+   --  message. Set by use of pragma Implicit_Packing.
 
    Init_Or_Norm_Scalars : Boolean := False;
    --  GNAT, GNATBIND