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