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

The strategy to expand aggregates present as initialization expressions in
object declarations, originally with a subsequent address clause given for
the object and later with aspects whose resolution needs to be delayed up
to the freeze point, has been to block their resolution, so as to block
their expansion, during the processing of the declarations, lest they be
nonstatic and expanded in place and therefore generate assignments to the
object before its freeze point, which is forbidden.  Instead a temporary
is created at the declaration point and the aggregates are assigned to it,
and finally the temporary is copied into the object at the freeze point.

Of course this general strategy cannot be applied to limited types because
the copy operation is forbidden for them, so instead aggregates of limited
types are resolved but have their expansion delayed, before being eventually
expanded through Convert_Aggr_In_Object_Decl, which uses the mechanism based
on Initialization_Statements to insert them at the freeze point.

After the series of cleanups, all the aggregates that are initialization
expressions in object declarations and get expanded in place, go through the
Convert_Aggr_In_Object_Decl mechanism, exactly like those of limited type
with address clause/aspects have done historically.  This means that we no
longer need to block the resolution of those of nonlimited type with address
clause/aspects.

gcc/ada/ChangeLog:

        * exp_ch3.adb: Remove clauses for Expander.
        (Expand_N_Object_Declaration): Remove special processing for delayed
        aggregates of limited types as initialization expressions.
        * freeze.adb (Warn_Overlay): Bail out if No_Initialization is set on
        the declaration node of the entity.
        * sem_ch3.adb (Delayed_Aspect_Present): Delete.
        (Expand_N_Object_Declaration): Do not block the resolution of the
        initialization expression that is an aggregate when the object has
        an address clause or delayed aspects.

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

---
 gcc/ada/exp_ch3.adb | 24 ++----------
 gcc/ada/freeze.adb  |  6 +++
 gcc/ada/sem_ch3.adb | 92 ++++++---------------------------------------
 3 files changed, 22 insertions(+), 100 deletions(-)

diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 639fe50cd53..7d8a7fd4fed 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -32,7 +32,6 @@ with Einfo;          use Einfo;
 with Einfo.Entities; use Einfo.Entities;
 with Einfo.Utils;    use Einfo.Utils;
 with Errout;         use Errout;
-with Expander;       use Expander;
 with Exp_Aggr;       use Exp_Aggr;
 with Exp_Atag;       use Exp_Atag;
 with Exp_Ch4;        use Exp_Ch4;
@@ -7701,28 +7700,13 @@ package body Exp_Ch3 is
 
          Expr_Q := Unqualify (Expr);
 
-         --  When we have the appropriate type of aggregate in the expression
-         --  (it has been determined during analysis of the aggregate by
-         --  setting the delay flag), let's perform in place assignment and
-         --  thus avoid creating a temporary.
+         --  When we have the appropriate kind of aggregate in the expression
+         --  (this has been determined during analysis of the aggregate by
+         --  setting the Expansion_Delayed flag), let's perform in place
+         --  assignment and thus avoid creating a temporary.
 
          if Is_Delayed_Aggregate (Expr_Q) then
 
-            --  An aggregate that must be built in place is not resolved and
-            --  expanded until the enclosing construct is expanded. This will
-            --  happen when the aggregate is limited and the declared object
-            --  has a following address clause. Resolution is done without
-            --  expansion because it will take place when the declaration
-            --  itself is expanded.
-
-            if Is_Limited_Type (Typ)
-              and then not Analyzed (Expr)
-            then
-               Expander_Mode_Save_And_Set (False);
-               Resolve (Expr, Typ);
-               Expander_Mode_Restore;
-            end if;
-
             --  For a special return object, the transformation must wait until
             --  after the object is turned into an allocator.
 
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 67a51899f95..b52898f4212 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -11034,6 +11034,12 @@ package body Freeze is
          return;
       end if;
 
+      --  No warning if there is no default initialization
+
+      if No_Initialization (Declaration_Node (Ent)) then
+         return;
+      end if;
+
       --  We only give the warning for non-imported entities of a type for
       --  which a non-null base init proc is defined, or for objects of access
       --  types with implicit null initialization, or when Normalize_Scalars
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index aa950692473..4a3d020330c 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -3874,17 +3874,6 @@ package body Sem_Ch3 is
       --  or a variant record type is encountered, Check_Restriction is called
       --  indicating the count is unknown.
 
-      function Delayed_Aspect_Present return Boolean;
-      --  If the declaration has an expression that is an aggregate, and it
-      --  has aspects that require delayed analysis, the resolution of the
-      --  aggregate must be deferred to the freeze point of the object. This
-      --  special processing was created for address clauses, but it must
-      --  also apply to address aspects. This must be done before the aspect
-      --  specifications are analyzed because we must handle the aggregate
-      --  before the analysis of the object declaration is complete.
-
-      --  Any other relevant delayed aspects on object declarations ???
-
       -----------------------------------
       -- Apply_External_Initialization --
       -----------------------------------
@@ -4326,35 +4315,6 @@ package body Sem_Ch3 is
          end if;
       end Count_Tasks;
 
-      ----------------------------
-      -- Delayed_Aspect_Present --
-      ----------------------------
-
-      function Delayed_Aspect_Present return Boolean is
-         A    : Node_Id;
-         A_Id : Aspect_Id;
-
-      begin
-         A := First (Aspect_Specifications (N));
-
-         while Present (A) loop
-            A_Id := Get_Aspect_Id (Chars (Identifier (A)));
-
-            if A_Id = Aspect_Address then
-
-               --  Set flag on object entity, for later processing at the
-               --  freeze point.
-
-               Set_Has_Delayed_Aspects (Id);
-               return True;
-            end if;
-
-            Next (A);
-         end loop;
-
-         return False;
-      end Delayed_Aspect_Present;
-
       --  Local variables
 
       Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
@@ -4667,51 +4627,23 @@ package body Sem_Ch3 is
 
          Set_Etype (Id, T);
 
-         --  If the expression is an aggregate we must look ahead to detect
-         --  the possible presence of an address clause, and defer resolution
-         --  and expansion of the aggregate to the freeze point of the entity.
+         --  If the expression is a formal that is a "subprogram pointer"
+         --  this is illegal in accessibility terms (see RM 3.10.2 (13.1/2)
+         --  and AARM 3.10.2 (13.b/2)). Add an explicit conversion to force
+         --  the corresponding check, as is done for assignments.
 
-         --  This is not always legal because the aggregate may contain other
-         --  references that need freezing, e.g. references to other entities
-         --  with address clauses. In any case, when compiling with -gnatI the
-         --  presence of the address clause must be ignored.
-
-         if Comes_From_Source (N)
-           and then Expander_Active
-           and then Nkind (E) = N_Aggregate
+         if Is_Entity_Name (E)
+           and then Present (Entity (E))
+           and then Is_Formal (Entity (E))
            and then
-             ((Present (Following_Address_Clause (N))
-                 and then not Ignore_Rep_Clauses)
-              or else Delayed_Aspect_Present)
+             Ekind (Etype (Entity (E))) = E_Anonymous_Access_Subprogram_Type
+           and then Ekind (T) /= E_Anonymous_Access_Subprogram_Type
          then
-            Set_Etype (E, T);
-
-            --  If the aggregate is limited it will be built in place, and its
-            --  expansion is deferred until the object declaration is expanded.
-
-            if Is_Limited_Type (T) then
-               Set_Expansion_Delayed (E);
-            end if;
-
-         else
-            --  If the expression is a formal that is a "subprogram pointer"
-            --  this is illegal in accessibility terms (see RM 3.10.2 (13.1/2)
-            --  and AARM 3.10.2 (13.b/2)). Add an explicit conversion to force
-            --  the corresponding check, as is done for assignments.
-
-            if Is_Entity_Name (E)
-              and then Present (Entity (E))
-              and then Is_Formal (Entity (E))
-              and then
-                Ekind (Etype (Entity (E))) = E_Anonymous_Access_Subprogram_Type
-              and then Ekind (T) /= E_Anonymous_Access_Subprogram_Type
-            then
-               Rewrite (E, Convert_To (T, Relocate_Node (E)));
-            end if;
-
-            Resolve (E, T);
+            Rewrite (E, Convert_To (T, Relocate_Node (E)));
          end if;
 
+         Resolve (E, T);
+
          --  No further action needed if E is a call to an inlined function
          --  which returns an unconstrained type and it has been expanded into
          --  a procedure call. In that case N has been replaced by an object
-- 
2.43.0

Reply via email to