diff options
author | Arnaud Charlet <charlet@adacore.com> | 2020-12-17 03:09:00 -0500 |
---|---|---|
committer | Pierre-Marie de Rodat <derodat@adacore.com> | 2021-05-04 05:17:31 -0400 |
commit | 213c9dc78ecb2027e4691a6097c5fda6c2f06a63 (patch) | |
tree | 6c2fc34d82c35109ffbaade937b84dd440663d1f | |
parent | 869a06d981893b769829975bf27d8a3069cacf47 (diff) | |
download | gcc-213c9dc78ecb2027e4691a6097c5fda6c2f06a63.zip gcc-213c9dc78ecb2027e4691a6097c5fda6c2f06a63.tar.gz gcc-213c9dc78ecb2027e4691a6097c5fda6c2f06a63.tar.bz2 |
[Ada] Missing finalization on generic instantiation
gcc/ada/
* exp_ch7.adb (Build_Finalizer_Helper.New_Finalizer_Name):
Unnest so that it can be reused.
(Build_Finalizer_Helper.Process_Declarations): Call the
xxx__finalize_body procedure of a package instantiation in case
it contains finalization statements. Code clean ups.
(Build_Finalizer_Helper.Create_Finalizer): Export and set an
Interface_Name for library level finalizers since these may be
imported now.
(Build_Finalizer_Helper): Need to process library level package
body instantiations which may contain objects requiring
finalization.
* libgnat/s-finmas.ads: Fix typo.
-rw-r--r-- | gcc/ada/exp_ch7.adb | 209 | ||||
-rw-r--r-- | gcc/ada/libgnat/s-finmas.ads | 2 |
2 files changed, 150 insertions, 61 deletions
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb index bfb0062..0d7a644 100644 --- a/gcc/ada/exp_ch7.adb +++ b/gcc/ada/exp_ch7.adb @@ -1547,6 +1547,11 @@ package body Exp_Ch7 is -- Create the spec and body of the finalizer and insert them in the -- proper place in the tree depending on the context. + function New_Finalizer_Name + (Spec_Id : Node_Id; For_Spec : Boolean) return Name_Id; + -- Create a fully qualified name of a package spec or body finalizer. + -- The generated name is of the form: xx__yy__finalize_[spec|body]. + procedure Process_Declarations (Decls : List_Id; Preprocess : Boolean := False; @@ -1554,7 +1559,8 @@ package body Exp_Ch7 is -- Inspect a list of declarations or statements which may contain -- objects that need finalization. When flag Preprocess is set, the -- routine will simply count the total number of controlled objects in - -- Decls. Flag Top_Level denotes whether the processing is done for + -- Decls and set Counter_Val accordingly. Top_Level is only relevant + -- when Preprocess is set and if True, the processing is performed for -- objects in nested package declarations or instances. procedure Process_Object_Declaration @@ -1689,58 +1695,6 @@ package body Exp_Ch7 is ---------------------- procedure Create_Finalizer is - function New_Finalizer_Name return Name_Id; - -- Create a fully qualified name of a package spec or body finalizer. - -- The generated name is of the form: xx__yy__finalize_[spec|body]. - - ------------------------ - -- New_Finalizer_Name -- - ------------------------ - - function New_Finalizer_Name return Name_Id is - procedure New_Finalizer_Name (Id : Entity_Id); - -- Place "__<name-of-Id>" in the name buffer. If the identifier - -- has a non-standard scope, process the scope first. - - ------------------------ - -- New_Finalizer_Name -- - ------------------------ - - procedure New_Finalizer_Name (Id : Entity_Id) is - begin - if Scope (Id) = Standard_Standard then - Get_Name_String (Chars (Id)); - - else - New_Finalizer_Name (Scope (Id)); - Add_Str_To_Name_Buffer ("__"); - Add_Str_To_Name_Buffer (Get_Name_String (Chars (Id))); - end if; - end New_Finalizer_Name; - - -- Start of processing for New_Finalizer_Name - - begin - -- Create the fully qualified name of the enclosing scope - - New_Finalizer_Name (Spec_Id); - - -- Generate: - -- __finalize_[spec|body] - - Add_Str_To_Name_Buffer ("__finalize_"); - - if For_Package_Spec then - Add_Str_To_Name_Buffer ("spec"); - else - Add_Str_To_Name_Buffer ("body"); - end if; - - return Name_Find; - end New_Finalizer_Name; - - -- Local variables - Body_Id : Entity_Id; Fin_Body : Node_Id; Fin_Spec : Node_Id; @@ -1748,8 +1702,6 @@ package body Exp_Ch7 is Label : Node_Id; Label_Id : Entity_Id; - -- Start of processing for Create_Finalizer - begin -- Step 1: Creation of the finalizer name @@ -1760,7 +1712,8 @@ package body Exp_Ch7 is -- xx__yy__finalize_[spec|body] if For_Package then - Fin_Id := Make_Defining_Identifier (Loc, New_Finalizer_Name); + Fin_Id := Make_Defining_Identifier + (Loc, New_Finalizer_Name (Spec_Id, For_Package_Spec)); Set_Has_Qualified_Name (Fin_Id); Set_Has_Fully_Qualified_Name (Fin_Id); @@ -1836,10 +1789,22 @@ package body Exp_Ch7 is Make_Procedure_Specification (Loc, Defining_Unit_Name => Fin_Id)); + if For_Package then + Set_Is_Exported (Fin_Id); + Set_Interface_Name (Fin_Id, + Make_String_Literal (Loc, + Strval => Get_Name_String (Chars (Fin_Id)))); + end if; + -- Step 3: Creation of the finalizer body - if Has_Ctrl_Objs then + -- Has_Ctrl_Objs might be set because of a generic package body having + -- controlled objects. In this case, Jump_Alts may be empty and no + -- case nor goto statements are needed. + if Has_Ctrl_Objs + and then not Is_Empty_List (Jump_Alts) + then -- Add L0, the default destination to the jump block Label_Id := Make_Identifier (Loc, New_External_Name ('L', 0)); @@ -2161,6 +2126,54 @@ package body Exp_Ch7 is Set_Is_Checked_Ghost_Entity (Fin_Id, False); end Create_Finalizer; + ------------------------ + -- New_Finalizer_Name -- + ------------------------ + + function New_Finalizer_Name + (Spec_Id : Node_Id; For_Spec : Boolean) return Name_Id + is + procedure New_Finalizer_Name (Id : Entity_Id); + -- Place "__<name-of-Id>" in the name buffer. If the identifier + -- has a non-standard scope, process the scope first. + + ------------------------ + -- New_Finalizer_Name -- + ------------------------ + + procedure New_Finalizer_Name (Id : Entity_Id) is + begin + if Scope (Id) = Standard_Standard then + Get_Name_String (Chars (Id)); + + else + New_Finalizer_Name (Scope (Id)); + Add_Str_To_Name_Buffer ("__"); + Get_Name_String_And_Append (Chars (Id)); + end if; + end New_Finalizer_Name; + + -- Start of processing for New_Finalizer_Name + + begin + -- Create the fully qualified name of the enclosing scope + + New_Finalizer_Name (Spec_Id); + + -- Generate: + -- __finalize_[spec|body] + + Add_Str_To_Name_Buffer ("__finalize_"); + + if For_Spec then + Add_Str_To_Name_Buffer ("spec"); + else + Add_Str_To_Name_Buffer ("body"); + end if; + + return Name_Find; + end New_Finalizer_Name; + -------------------------- -- Process_Declarations -- -------------------------- @@ -2540,6 +2553,73 @@ package body Exp_Ch7 is end if; end if; + -- Call the xxx__finalize_body procedure of a library level + -- package instantiation if the body contains finalization + -- statements. + + if Present (Generic_Parent (Spec)) + and then Is_Library_Level_Entity (Pack_Id) + and then Present (Body_Entity (Generic_Parent (Spec))) + then + if Preprocess then + declare + P : Node_Id; + begin + P := Parent (Body_Entity (Generic_Parent (Spec))); + while Present (P) + and then Nkind (P) /= N_Package_Body + loop + P := Parent (P); + end loop; + + if Present (P) then + Old_Counter_Val := Counter_Val; + Process_Declarations (Declarations (P), Preprocess); + + -- Note that we are processing the generic body + -- template and not the actually instantiation + -- (which is generated too late for us to process + -- it), so there is no need to update in particular + -- to update Last_Top_Level_Ctrl_Construct here. + + if Counter_Val > Old_Counter_Val then + Counter_Val := Old_Counter_Val; + Set_Has_Controlled_Component (Pack_Id); + end if; + end if; + end; + + elsif Has_Controlled_Component (Pack_Id) then + + -- We import the xxx__finalize_body routine since the + -- generic body will be instantiated later. + + declare + Id : constant Node_Id := + Make_Defining_Identifier (Loc, + New_Finalizer_Name (Defining_Unit_Name (Spec), + For_Spec => False)); + + begin + Set_Has_Qualified_Name (Id); + Set_Has_Fully_Qualified_Name (Id); + Set_Is_Imported (Id); + Set_Has_Completion (Id); + Set_Interface_Name (Id, + Make_String_Literal (Loc, + Strval => Get_Name_String (Chars (Id)))); + + Append_New_To (Finalizer_Stmts, + Make_Subprogram_Declaration (Loc, + Make_Procedure_Specification (Loc, + Defining_Unit_Name => Id))); + Append_To (Finalizer_Stmts, + Make_Procedure_Call_Statement (Loc, + Name => New_Occurrence_Of (Id, Loc))); + end; + end if; + end if; + -- Nested package bodies, avoid generics elsif Nkind (Decl) = N_Package_Body then @@ -2550,8 +2630,7 @@ package body Exp_Ch7 is if Is_Ignored_Ghost_Entity (Defining_Entity (Decl)) then null; - elsif Ekind (Corresponding_Spec (Decl)) /= - E_Generic_Package + elsif Ekind (Corresponding_Spec (Decl)) /= E_Generic_Package then Old_Counter_Val := Counter_Val; Process_Declarations (Declarations (Decl), Preprocess); @@ -3041,6 +3120,8 @@ package body Exp_Ch7 is -- Otherwise the initialization calls follow the related object else + pragma Assert (Present (Stmt)); + Stmt_2 := Next_Suitable_Statement (Stmt); -- Check for an optional call to Deep_Initialize which may @@ -3542,6 +3623,14 @@ package body Exp_Ch7 is or else Scope_Depth_Value (Spec_Id) /= Uint_1 or else (Is_Generic_Instance (Spec_Id) and then Package_Instantiation (Spec_Id) /= N)) + + -- Still need to process package body instantiations which may + -- contain objects requiring finalization. + + and then not + (For_Package_Body + and then Is_Library_Level_Entity (Spec_Id) + and then Is_Generic_Instance (Spec_Id)) then return; end if; @@ -3623,7 +3712,7 @@ package body Exp_Ch7 is -- Step 3: Finalizer creation - if Acts_As_Clean or else Has_Ctrl_Objs or else Has_Tagged_Types then + if Acts_As_Clean or Has_Ctrl_Objs or Has_Tagged_Types then Create_Finalizer; end if; end Build_Finalizer_Helper; diff --git a/gcc/ada/libgnat/s-finmas.ads b/gcc/ada/libgnat/s-finmas.ads index c3ebb9c..ea5a3fb 100644 --- a/gcc/ada/libgnat/s-finmas.ads +++ b/gcc/ada/libgnat/s-finmas.ads @@ -74,7 +74,7 @@ package System.Finalization_Masters is for Finalization_Master_Ptr'Storage_Size use 0; procedure Attach (N : not null FM_Node_Ptr; L : not null FM_Node_Ptr); - -- Compiler interface, do not call from withing the run-time. Prepend a + -- Compiler interface, do not call from within the run-time. Prepend a -- node to a specific finalization master. procedure Attach_Unprotected |