[COMMITTED,11/31] ada: Allow implicit packing of arrays when larger than needed

Message ID 20250911091904.1505690-11-poulhies@adacore.com
State Committed
Commit e39c326733d0cd20403ac1ccc578d9c63f3d0aa8
Headers
Series [COMMITTED,01/31] ada: Disable new warning for composite equality ops that can raise Program_Error |

Commit Message

Marc Poulhiès Sept. 11, 2025, 9:18 a.m. UTC
  From: Bob Duff <duff@adacore.com>

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.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/freeze.adb | 43 +++++++++++++++++++++----------------------
 gcc/ada/opt.ads    |  6 +++---
 2 files changed, 24 insertions(+), 25 deletions(-)
  

Patch

diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 8fa25b3d8510..1bbc24f62fe2 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -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
+                     if Implicit_Packing
+                       and then RM_Size (E) >= Num_Elmts * Rsiz
+                     then
+                        Set_Component_Size (Btyp, Rsiz);
 
-                        --  For implicit packing mode, just set the component
-                        --  size and Freeze_Array_Type will do the rest.
+                     --  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.
 
-                        if Implicit_Packing 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.
-
-                        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;
diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads
index 524a823bb8f6..109d28245de9 100644
--- a/gcc/ada/opt.ads
+++ b/gcc/ada/opt.ads
@@ -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