A reference to an element of a packed array is rewritten through conversions and masks and shifts. If the prefix of the reference is a source entity we must generate a reference to it for cross-reference purposes, and to prevent spurious warnings about unused entities.
Compiling gcc -c -gnatwa case_2.adb must yield: case_2.adb:10:06: warning: unit "System" is not referenced case_2.adb:37:13: warning: 1 bits of "Storage_Record_Type" unused -- -- Test case for anomalous GNAT compiler warning. -- Compile as follows: -- gnatmake -f -gnatwf case_2 -- -- This will create a warning that the formal parameter "Storage" of the -- function Test_Function is not referenced, even though it is. -- with System; with Text_IO; procedure Case_2 is -- -- 32-bit signed integer type -- type My_Long is range -(2 ** 31) .. +(2 ** 31) - 1; for My_Long'size use 32; -- -- Changing this to 64 will prevent the warning from being reported. -- Record_Size : constant := 65; -- -- Note: this type is defined as having an extra bit unused for ease of -- switching the size to 64 to see the warning go away. -- Even adding an extra field to fill in the unused bit, GNAT still -- reports the warning. -- type Storage_Record_Type is record E : My_Long; F : My_Long; end record with Size => Record_Size; type My_Storage_Array_Type is array (My_Long range <>) of Storage_Record_Type with Pack => True; -- -- GNAT gives a warning that "Storage" is not used. -- function Test_Function (Storage : in My_Storage_Array_Type; Left : in My_Long; Right : in My_Long) return Boolean is begin return Storage (Left).E < Storage (Right).F; end Test_Function; -- -- Dummy variables to support the below code. -- Test : My_Storage_Array_Type (1 .. 1); Result : Boolean; begin -- -- This small bit of code is only here to ensure that none of the above -- parts get optimized out during compilation. -- Test (1) := (E => 0, F => 0); Result := Test_Function (Test, 1, 1); Text_IO.Put_Line (Boolean'image (Result)); end Case_2; Tested on x86_64-pc-linux-gnu, committed on trunk 2014-10-23 Ed Schonberg <schonb...@adacore.com> * exp_pakd.adb (Expand_Packed_Element_Reference): If the prefix is a source entity, generate a reference to it before transformation, because rewritten node might not generate a proper reference, leading to spurious warnings.
Index: exp_pakd.adb =================================================================== --- exp_pakd.adb (revision 216574) +++ exp_pakd.adb (working copy) @@ -30,6 +30,7 @@ with Exp_Dbug; use Exp_Dbug; with Exp_Util; use Exp_Util; with Layout; use Layout; +with Lib.Xref; use Lib.Xref; with Namet; use Namet; with Nlists; use Nlists; with Nmake; use Nmake; @@ -1682,6 +1683,16 @@ Expand_Packed_Element_Reference (Prefix (N)); end if; + -- The prefix may be rewritten below as a conversion. If it is a source + -- entity generate reference to it now, to prevent spurious warnings + -- about unused entities. + + if Is_Entity_Name (Prefix (N)) + and then Comes_From_Source (Prefix (N)) + then + Generate_Reference (Entity (Prefix (N)), Prefix (N), 'r'); + end if; + -- If not bit packed, we have the enumeration case, which is easily -- dealt with (just adjust the subscripts of the indexed component)