[COMMITTED] ada: Fix missing finalization in library-unit instance spec
Checks
Commit Message
From: Eric Botcazou <ebotcazou@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(-)
@@ -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,
@@ -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
@@ -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