From: Eric Botcazou <ebotca...@adacore.com> This fixes the missing finalization of objects declared in the spec of package instances that are library units (and only them, i.e. not all library-level package instances) when the instances have a package body.
The finalization is done when there is no package body, and supporting this case precisely broke the other case because of a thinko or a typo. This also requires a small adjustment to the routine writing ALI files. gcc/ada/ * exp_ch7.adb (Build_Finalizer): Reverse the test comparing the instantiation and declaration nodes of a package instance, and therefore bail out only when they are equal. Adjust comments. (Expand_N_Package_Declaration): Do not clear the Finalizer field. * lib-writ.adb: Add with and use clauses for Sem_Util. (Write_Unit_Information): Look at unit nodes to find finalizers. * sem_ch12.adb (Analyze_Package_Instantiation): Beef up the comment about the rewriting of the instantiation node into a declaration. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/exp_ch7.adb | 18 +++++++++++++----- gcc/ada/lib-writ.adb | 19 +++++++++++++++---- gcc/ada/sem_ch12.adb | 10 ++++++---- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb index 7ea39f7ba16..a02e28e4b34 100644 --- a/gcc/ada/exp_ch7.adb +++ b/gcc/ada/exp_ch7.adb @@ -3534,15 +3534,21 @@ package body Exp_Ch7 is and then (not Is_Library_Level_Entity (Spec_Id) - -- Nested packages are library level entities, but do not need to + -- Nested packages are library-level entities, but do not need to -- be processed separately. or else Scope_Depth (Spec_Id) /= Uint_1 + + -- Do not build two finalizers for an instance without body that + -- is a library unit (see Analyze_Package_Instantiation). + or else (Is_Generic_Instance (Spec_Id) - and then Package_Instantiation (Spec_Id) /= N)) + and then Package_Instantiation (Spec_Id) = N)) - -- Still need to process package body instantiations which may - -- contain objects requiring finalization. + -- Still need to process library-level package body instances, whose + -- instantiation was deferred and thus could not be seen during the + -- processing of the enclosing scope, and which may contain objects + -- requiring finalization. and then not (For_Package_Body @@ -5376,7 +5382,9 @@ package body Exp_Ch7 is Defer_Abort => False, Fin_Id => Fin_Id); - Set_Finalizer (Id, Fin_Id); + if Present (Fin_Id) then + Set_Finalizer (Id, Fin_Id); + end if; end if; -- If this is a library-level package and unnesting is enabled, diff --git a/gcc/ada/lib-writ.adb b/gcc/ada/lib-writ.adb index deecfc067c5..23b6266bb41 100644 --- a/gcc/ada/lib-writ.adb +++ b/gcc/ada/lib-writ.adb @@ -50,6 +50,7 @@ with Rident; use Rident; with Stand; use Stand; with Scn; use Scn; with Sem_Eval; use Sem_Eval; +with Sem_Util; use Sem_Util; with Sinfo; use Sinfo; with Sinfo.Nodes; use Sinfo.Nodes; with Sinfo.Utils; use Sinfo.Utils; @@ -524,10 +525,20 @@ package body Lib.Writ is Write_Info_Str (" O"); Write_Info_Char (OA_Setting (Unit_Num)); - if Ekind (Uent) in E_Package | E_Package_Body - and then Present (Finalizer (Uent)) - then - Write_Info_Str (" PF"); + -- For a package instance with a body that is a library unit, the two + -- compilation units share Cunit_Entity so we cannot rely on Uent. + + if Ukind in N_Package_Declaration | N_Package_Body then + declare + E : constant Entity_Id := Defining_Entity (Unit (Unode)); + + begin + if Ekind (E) in E_Package | E_Package_Body + and then Present (Finalizer (E)) + then + Write_Info_Str (" PF"); + end if; + end; end if; if Is_Preelaborated (Uent) then diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb index 181392c2132..c31d0c62faa 100644 --- a/gcc/ada/sem_ch12.adb +++ b/gcc/ada/sem_ch12.adb @@ -5007,10 +5007,12 @@ package body Sem_Ch12 is Set_First_Private_Entity (Defining_Unit_Name (Unit_Renaming), First_Private_Entity (Act_Decl_Id)); - -- If the instantiation will receive a body, the unit will be - -- transformed into a package body, and receive its own elaboration - -- entity. Otherwise, the nature of the unit is now a package - -- declaration. + -- If the instantiation needs a body, the unit will be turned into + -- a package body and receive its own elaboration entity. Otherwise, + -- the nature of the unit is now a package declaration. + + -- Note that the below rewriting means that Act_Decl, which has been + -- analyzed and expanded, will be re-expanded as the rewritten N. if Nkind (Parent (N)) = N_Compilation_Unit and then not Needs_Body -- 2.40.0