From: Eric Botcazou <ebotca...@adacore.com>

This was initially implemented as part of AI12-001 but immediately disabled
because it breaks Florist on 32-bit platforms.  However, it is possible to
reenable it in almost all cases without affecting Florist, and the -gnatd_l
switch can now be used to disable it again.

gcc/ada/
        * debug.adb (d_l): Document new usage for the compiler.
        * freeze.adb (Check_Strict_Alignment): Set the Strict_Alignment
        flag on array types with aliased component, except if the
        component size is equal to the storage unit or the -gnatd_l switch
        is specified.

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

---
 gcc/ada/debug.adb  |  5 ++++-
 gcc/ada/freeze.adb | 30 ++++++++++++++++++------------
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb
index 97f88b7664f..f7fcd399769 100644
--- a/gcc/ada/debug.adb
+++ b/gcc/ada/debug.adb
@@ -148,7 +148,7 @@ package body Debug is
    --  d_i  Ignore activations and calls to instances for elaboration
    --  d_j  Read JSON files and populate Repinfo tables (opposite of -gnatRjs)
    --  d_k  In CodePeer mode disable expansion of assertion checks
-   --  d_l
+   --  d_l  Disable strict alignment of array types with aliased component
    --  d_m
    --  d_n
    --  d_o
@@ -989,6 +989,9 @@ package body Debug is
    --       enabled, expansion of assertion expressions is controlled by
    --       pragma Assertion_Policy.
 
+   --  d_l  The compiler does not enforce the strict alignment of array types
+   --       that are declared with an aliased component.
+
    --  d_p  The compiler ignores calls to subprograms which verify the run-time
    --       semantics of invariants and postconditions in both the static and
    --       dynamic elaboration models.
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index d0dd1de087d..3c3d038c392 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -2374,18 +2374,24 @@ package body Freeze is
       elsif Is_Array_Type (E) then
          Set_Strict_Alignment (E, Strict_Alignment (Component_Type (E)));
 
-         --  ??? AI12-001: Any component of a packed type that contains an
-         --  aliased part must be aligned according to the alignment of its
-         --  subtype (RM 13.2(7)). This means that the following test:
-
-         --    if Has_Aliased_Components (E) then
-         --      Set_Strict_Alignment (E);
-         --    end if;
-
-         --  should be implemented here. Unfortunately it would break Florist,
-         --  which has the bad habit of overaligning all the types it declares
-         --  on 32-bit platforms. Other legacy codebases could also be affected
-         --  because this check has historically been missing in GNAT.
+         --  RM 13.2(7.1/4): Any component of a packed type that contains an
+         --  aliased part shall be aligned according to the alignment of its
+         --  subtype.
+
+         --  Unfortunately this breaks Florist, which has had the bad habit
+         --  of overaligning all the types it declares on 32-bit platforms,
+         --  so make an exception if the component size is the storage unit.
+
+         --  Other legacy codebases could also be affected because this was
+         --  historically not enforced, so -gnatd_l can be used to disable it.
+
+         if Has_Aliased_Components (E)
+           and then not (Known_Component_Size (E)
+                          and then Component_Size (E) = System_Storage_Unit)
+           and then not Debug_Flag_Underscore_L
+         then
+            Set_Strict_Alignment (E);
+         end if;
 
       elsif Is_Record_Type (E) then
          Comp := First_Component (E);
-- 
2.45.1

Reply via email to