]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada: Cleanup in expansion of aggregates in object declarations with aspects
authorEric Botcazou <ebotcazou@adacore.com>
Fri, 8 Nov 2024 19:50:52 +0000 (20:50 +0100)
committerMarc Poulhiès <dkm@gcc.gnu.org>
Tue, 19 Nov 2024 12:58:50 +0000 (13:58 +0100)
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.

gcc/ada/exp_ch3.adb
gcc/ada/freeze.adb
gcc/ada/sem_ch3.adb

index 639fe50cd5300b58197d5ec96ea71572f2c4295e..7d8a7fd4fedcc11825a88df84b05d3e18a2e0f82 100644 (file)
@@ -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.
 
index 67a51899f951dbecec3a3245521129220542965a..b52898f421210ebb6e0898af39c2ccb0d9ea0f0e 100644 (file)
@@ -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
index aa950692473f31e9dccfdbcf0b36330c16caef4b..4a3d020330ca5c7a34806d5cb909d78af2a27a27 100644 (file)
@@ -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