This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Finalization of components when Initialize fails


This patch plugs a long existing hole (think 1990s) in the implementation of
controlled types. The initialization of a controlled object with controlled
components is performed by two separate routines - components are handled by
the type init proc and the object initialization by [Deep_]Initialize:

   Type_Init_Proc (The_Object);     --  initialize components
   [Deep_]Initialize (The_Object);  --  invoke user-defined Initialize

Due to this approach, a potential exception raised by [Deep_]Initialize did not
until now properly finalize all successfully initialized components. The patch
also addresses a few dormant issues related to the successfull initialization
of objects by means of aggregates.

------------
-- Source --
------------

--  types.ads

with Ada.Finalization; use Ada.Finalization;

package Types is
    type Ctrl_Comp is new Controlled with null record;
    procedure Initialize (Obj : in out Ctrl_Comp);
    procedure Finalize   (Obj : in out Ctrl_Comp);

    type Ctrl is new Controlled with record
       Comp : Ctrl_Comp;
    end record;
    procedure Initialize (Obj : in out Ctrl);
    procedure Finalize   (Obj : in out Ctrl);

    Initialization_Interrupt : Exception;
end Types;

--  types.adb

with Ada.Text_IO; use Ada.Text_IO;

package body Types is
    procedure Initialize (Obj : in out Ctrl_Comp) is
    begin
       Put_Line ("ini Ctrl_Comp");
    end Initialize;
    procedure Finalize (Obj : in out Ctrl_Comp) is
    begin
       Put_Line ("fin Ctrl_Comp");
    end Finalize;

    procedure Initialize (Obj : in out Ctrl) is
    begin
       Put_Line ("ini Ctrl");
       raise Initialization_Interrupt;
    end Initialize;

    procedure Finalize (Obj : in out Ctrl) is
    begin
       Put_Line ("Should this be called?");
    end Finalize;
end Types;

--  main.adb

with Ada.Text_IO; use Ada.Text_IO;
with Types;       use Types;

procedure Main is
    Obj : Ctrl;

begin
    Put_Line ("Main");

end Main;

----------------------------
-- Compilation and output --
----------------------------

$ gnatmake -q main.adb
$ ./main
ini Ctrl_Comp
ini Ctrl
fin Ctrl_Comp

raised TYPES.INITIALIZATION_INTERRUPT : types.adb:16

Tested on x86_64-pc-linux-gnu, committed on trunk

2014-07-18  Hristian Kirtchev  <kirtchev@adacore.com>

	* einfo.adb Last_Aggregate_Assignment is now Node 30.
	(Last_Aggregate_Assignment): Include
	constants in the assertion. Update the underlying node.
	(Set_Last_Aggregate_Assignment): Include constants in the
	assertion. Update the underlying node.	(Write_Field11_Name):
	Remove the entry for Last_Aggregate_Assignment.
	(Write_Field30_Name): Add an entry for Last_Aggregate_Assignment.
	* einfo.ads Update the node designation and usage of attribute
	Last_Aggregate_Assignment.
	* exp_aggr.adb (Expand_Array_Aggregate): Store the last
	assignment statement used to initialize a controlled object.
	(Late_Expansion): Store the last assignment statement used to
	initialize a controlled record or an array of controlled objects.
	* exp_ch3.adb (Expand_N_Object_Declaration): Default
	initialization of objects is now performed in a separate routine.
	(Default_Initialize_Object): New routine.
	* exp_ch7.adb (Build_BIP_Cleanup_Stmts): Add formal parameter
	Obj_Id. Update the comment on usage.
	(Find_Last_Init): Remove formal parameter Typ. Update comment on usage.
	Reimplement the logic.	(Find_Last_Init_In_Block): New routine.
	(Is_Init_Call): Add formal parameter Init_Typ. Update the
	comment on usage.  Account for the type init proc when trying
	to determine whether a statement is an initialization call.
	(Make_Adjust_Call): Rename formal parameter For_Parent to
	Skip_Self. Update all occurrences of For_Parent. Account for
	non-tagged types. Update the call to Make_Call.
	(Make_Call): Rename formal parameter For_Parent to Skip_Self. Update
	comment on usage. Update all occurrences of For_Parent.
	(Make_Final_Call): Rename formal parameter For_Parent to
	Skip_Self. Update all occurrences of For_Parent. Account
	for non-tagged types. Update the call to Make_Call.
	(Process_Object_Declaration): Most variables and constants are
	now local to the routine.
	* exp_ch7.ads (Make_Adjust_Call): Rename formal parameter
	For_Parent to Skip_Self. Update the comment on usage.
	(Make_Final_Call): Rename formal parameter For_Parent to
	Skip_Self. Update the comment on usage.

Attachment: difs
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]