This patch removes a spurious error on a unit to which the Preelaborate
pragma applies. The error appeared on a unit that holds an instantiation of
a package containing a type declaration with an array component whose default
value is given by an actual in the instance, but the error may occur in other
contexts. The improper error depended on the size of the array aggregate and
whether it was given by an Others clause or an explicit range. The semantics
of the pragma must of course be independent of the size of the array, as long
as its expressions obey preelaborate conditions.

The following must compile quietly:

   gcc -c preelab.adb

---
with Types;
with Data;
procedure Preelab is
   X : Data.Name_Type_Array.List (2);
begin
   if Types.Length (Types.Chars (X.Item (1))) > 0 then -- junk code
      X.Item (2) := X.Item (1);
   end if;
end Preelab;
---
generic
   type Element is private;
   Null_Element : in Element;
package Arrays is
   pragma Preelaborate;

   type Index_Array is array (Positive range <>) of Element;

   type List (Size : Positive); -- must be public for embedding

   type Access_Key_List is access all List;

   type List (Size : Positive) is record -- must be public for embedding
      Item : Index_Array (1 .. Size) := (others => Null_Element);
      Used : Natural := 0;
      Next : Access_Key_List;
   end record;
end Arrays;
---
with Arrays;
with Types;
package Data is
   pragma Preelaborate;
   type Name_Type is new Types.Chars (1 .. Types.Last);
   package Name_Type_Array is new Arrays (Name_Type, (others => ' '));
end Data;
---
package Types is
   pragma Preelaborate;
   Last : constant := 10004;
   subtype Chars is Wide_String;
   function Length (Item : in Chars) return Natural;
end;

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

2014-06-13  Ed Schonberg  <schonb...@adacore.com>

        * sem_cat.adb (Validate_Static_Object_Name): A constant whose
        value is a temporary that renames an aggregate is legal in a
        preelaborated unit. Illegalities, if any will be detected in
        the aggregate components.

Index: sem_cat.adb
===================================================================
--- sem_cat.adb (revision 211609)
+++ sem_cat.adb (working copy)
@@ -2048,7 +2048,8 @@
    ---------------------------------
 
    procedure Validate_Static_Object_Name (N : Node_Id) is
-      E : Entity_Id;
+      E   : Entity_Id;
+      Val : Node_Id;
 
       function Is_Primary (N : Node_Id) return Boolean;
       --  Determine whether node is syntactically a primary in an expression
@@ -2151,7 +2152,8 @@
          elsif Ekind (Entity (N)) = E_Constant
            and then not Is_Static_Expression (N)
          then
-            E := Entity (N);
+            E   := Entity (N);
+            Val := Constant_Value (E);
 
             if Is_Internal_File_Name (Unit_File_Name (Get_Source_Unit (N)))
               and then
@@ -2169,6 +2171,21 @@
             then
                null;
 
+            --  If the value of the constant is a local variable that renames
+            --  an aggregate, this is in itself legal. The aggregate may be
+            --  expanded into a loop, but this does not affect preelaborability
+            --  in itself. If some aggregate components are non-static, that is
+            --  to say if they involve non static primaries, they will be
+            --  flagged when analyzed.
+
+            elsif Present (Val)
+              and then Is_Entity_Name (Val)
+              and then Is_Array_Type (Etype (Val))
+              and then not Comes_From_Source (Val)
+             and then Nkind (Original_Node (Val)) = N_Aggregate
+            then
+               null;
+
             --  This is the error case
 
             else

Reply via email to