This completes the previous fix, which is not sufficient when the Size
attribute is applied to a formal object of mode In Out and the generic
is instantiated on a slice of a bit-packed array whose size is not a
multiple of the storage unit.

The hurdle here is that introducing a temporary may change the value
of the Size attribute, because a temporary is a stand-alone object and
the size of stand-alone objects is always a multiple of the storage
unit with GNAT.

Instead of trying to look through them in Expand_Size_Attribute, this
changes the expansion done by Expand_N_Slice to avoid creating these
problematic temporaries for slices of bit-packed arrays that are the
prefix of the Size attribute.

Tested on x86_64-pc-linux-gnu, committed on trunk

2019-12-12  Eric Botcazou  <ebotca...@adacore.com>

gcc/ada/

        * exp_attr.adb (Expand_Size_Attribute): Look directly at the
        prefix to detect the bit-packed slices.  Apply the checks last
        in case the attribute needs to be processed by the back-end.
        * exp_ch4.adb (Expand_N_Slice): Do not create a temporary for
        a prefix of the Size attribute.
--- gcc/ada/exp_attr.adb
+++ gcc/ada/exp_attr.adb
@@ -7455,8 +7455,6 @@ package body Exp_Attr is
       --  All other cases are handled by the back end
 
       else
-         Apply_Universal_Integer_Attribute_Checks (N);
-
          --  If Size is applied to a formal parameter that is of a packed
          --  array subtype, then apply Size to the actual subtype.
 
@@ -7489,9 +7487,7 @@ package body Exp_Attr is
          --  System.Unsigned_Types.Packed_Byte for code generation purposes so
          --  the size is always rounded up in the back end.
 
-         elsif Nkind (Original_Node (Pref)) = N_Slice
-           and then Is_Bit_Packed_Array (Ptyp)
-         then
+         elsif Nkind (Pref) = N_Slice and then Is_Bit_Packed_Array (Ptyp) then
             Rewrite (N,
               Make_Op_Multiply (Loc,
                 Make_Attribute_Reference (Loc,
@@ -7503,6 +7499,9 @@ package body Exp_Attr is
             Analyze_And_Resolve (N, Typ);
          end if;
 
+         --  Apply the required checks last, after rewriting has taken place
+
+         Apply_Universal_Integer_Attribute_Checks (N);
          return;
       end if;
 

--- gcc/ada/exp_ch4.adb
+++ gcc/ada/exp_ch4.adb
@@ -11013,7 +11013,8 @@ package body Exp_Ch4 is
 
       --    5. Prefix of an address attribute (this is an error which is caught
       --       elsewhere, and the expansion would interfere with generating the
-      --       error message).
+      --       error message) or of a size attribute (because 'Size may change
+      --       when applied to the temporary instead of the slice directly).
 
       if not Is_Packed (Typ) then
 
@@ -11039,7 +11040,8 @@ package body Exp_Ch4 is
          return;
 
       elsif Nkind (Parent (N)) = N_Attribute_Reference
-        and then Attribute_Name (Parent (N)) = Name_Address
+        and then (Attribute_Name (Parent (N)) = Name_Address
+                   or else Attribute_Name (Parent (N)) = Name_Size)
       then
          return;
 

Reply via email to