From: charlet Date: Wed, 3 Oct 2012 08:09:15 +0000 (+0000) Subject: 2012-10-03 Javier Miranda X-Git-Tag: upstream/4.9.2~10220 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=693dfc0f8696e7c8a34f4ad2577cc3a8291cdaf2;p=platform%2Fupstream%2Flinaro-gcc.git 2012-10-03 Javier Miranda * exp_ch4.adb (Expand_N_Allocator_Expression): Minor code reorganization and cleanup. Done to ensure proper management of the C++ constructor covering tagged and untagged types and also non-default constructors. * exp_ch6.ads, exp_ch6.adb (Make_CPP_Constructor_Call_In_Allocator): New subprogram. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@192028 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 9c8bab6..7479da6 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,12 @@ +2012-10-03 Javier Miranda + + * exp_ch4.adb (Expand_N_Allocator_Expression): Minor code + reorganization and cleanup. Done to ensure proper management of + the C++ constructor covering tagged and untagged types and also + non-default constructors. + * exp_ch6.ads, exp_ch6.adb (Make_CPP_Constructor_Call_In_Allocator): + New subprogram. + 2012-10-03 Gary Dismukes * sem_ch6.adb: Minor typo fix. diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb index 223feac..9357be6 100644 --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -867,6 +867,15 @@ package body Exp_Ch4 is -- Start of processing for Expand_Allocator_Expression begin + -- Handle call to C++ constructor + + if Is_CPP_Constructor_Call (Exp) then + Make_CPP_Constructor_Call_In_Allocator + (Allocator => N, + Function_Call => Exp); + return; + end if; + -- In the case of an Ada 2012 allocator whose initial value comes from a -- function call, pass "the accessibility level determined by the point -- of call" (AI05-0234) to the function. Conceptually, this belongs in @@ -899,58 +908,6 @@ package body Exp_Ch4 is -- Case of tagged type or type requiring finalization if Is_Tagged_Type (T) or else Needs_Finalization (T) then - if Is_CPP_Constructor_Call (Exp) then - - -- Generate: - -- Pnnn : constant ptr_T := new (T); - -- Init (Pnnn.all,...); - - -- Allocate the object without an expression - - Node := Relocate_Node (N); - Set_Expression (Node, New_Reference_To (Etype (Exp), Loc)); - - -- Avoid its expansion to avoid generating a call to the default - -- C++ constructor. - - Set_Analyzed (Node); - - Temp := Make_Temporary (Loc, 'P', N); - - Temp_Decl := - Make_Object_Declaration (Loc, - Defining_Identifier => Temp, - Constant_Present => True, - Object_Definition => New_Reference_To (PtrT, Loc), - Expression => Node); - Insert_Action (N, Temp_Decl); - - Apply_Accessibility_Check (Temp); - - -- Locate the enclosing list and insert the C++ constructor call - - declare - P : Node_Id; - - begin - P := Parent (Node); - while not Is_List_Member (P) loop - P := Parent (P); - end loop; - - Insert_List_After_And_Analyze (P, - Build_Initialization_Call (Loc, - Id_Ref => - Make_Explicit_Dereference (Loc, - Prefix => New_Reference_To (Temp, Loc)), - Typ => Etype (Exp), - Constructor_Ref => Exp)); - end; - - Rewrite (N, New_Reference_To (Temp, Loc)); - Analyze_And_Resolve (N, PtrT); - return; - end if; -- Ada 2005 (AI-318-02): If the initialization expression is a call -- to a build-in-place function, then access to the allocated object diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb index 592c1f5..2fac2a3 100644 --- a/gcc/ada/exp_ch6.adb +++ b/gcc/ada/exp_ch6.adb @@ -9121,6 +9121,96 @@ package body Exp_Ch6 is end if; end Make_Build_In_Place_Call_In_Object_Declaration; + -------------------------------------------- + -- Make_CPP_Constructor_Call_In_Allocator -- + -------------------------------------------- + + procedure Make_CPP_Constructor_Call_In_Allocator + (Allocator : Node_Id; + Function_Call : Node_Id) + is + Loc : constant Source_Ptr := Sloc (Function_Call); + Acc_Type : constant Entity_Id := Etype (Allocator); + Function_Id : constant Entity_Id := Entity (Name (Function_Call)); + Result_Subt : constant Entity_Id := Available_View (Etype (Function_Id)); + + New_Allocator : Node_Id; + Return_Obj_Access : Entity_Id; + Tmp_Obj : Node_Id; + + begin + pragma Assert (Nkind (Allocator) = N_Allocator + and then Nkind (Function_Call) = N_Function_Call); + pragma Assert (Convention (Function_Id) = Convention_CPP + and then Is_Constructor (Function_Id)); + pragma Assert (Is_Constrained (Underlying_Type (Result_Subt))); + + -- Replace the initialized allocator of form "new T'(Func (...))" with + -- an uninitialized allocator of form "new T", where T is the result + -- subtype of the called function. The call to the function is handled + -- separately further below. + + New_Allocator := + Make_Allocator (Loc, + Expression => New_Reference_To (Result_Subt, Loc)); + Set_No_Initialization (New_Allocator); + + -- Copy attributes to new allocator. Note that the new allocator + -- logically comes from source if the original one did, so copy the + -- relevant flag. This ensures proper treatment of the restriction + -- No_Implicit_Heap_Allocations in this case. + + Set_Storage_Pool (New_Allocator, Storage_Pool (Allocator)); + Set_Procedure_To_Call (New_Allocator, Procedure_To_Call (Allocator)); + Set_Comes_From_Source (New_Allocator, Comes_From_Source (Allocator)); + + Rewrite (Allocator, New_Allocator); + + -- Create a new access object and initialize it to the result of the + -- new uninitialized allocator. Note: we do not use Allocator as the + -- Related_Node of Return_Obj_Access in call to Make_Temporary below + -- as this would create a sort of infinite "recursion". + + Return_Obj_Access := Make_Temporary (Loc, 'R'); + Set_Etype (Return_Obj_Access, Acc_Type); + + -- Generate: + -- Rnnn : constant ptr_T := new (T); + -- Init (Rnn.all,...); + + Tmp_Obj := + Make_Object_Declaration (Loc, + Defining_Identifier => Return_Obj_Access, + Constant_Present => True, + Object_Definition => New_Reference_To (Acc_Type, Loc), + Expression => Relocate_Node (Allocator)); + Insert_Action (Allocator, Tmp_Obj); + + Insert_List_After_And_Analyze (Tmp_Obj, + Build_Initialization_Call (Loc, + Id_Ref => + Make_Explicit_Dereference (Loc, + Prefix => New_Reference_To (Return_Obj_Access, Loc)), + Typ => Etype (Function_Id), + Constructor_Ref => Function_Call)); + + -- Finally, replace the allocator node with a reference to the result of + -- the function call itself (which will effectively be an access to the + -- object created by the allocator). + + Rewrite (Allocator, New_Reference_To (Return_Obj_Access, Loc)); + + -- Ada 2005 (AI-251): If the type of the allocator is an interface then + -- generate an implicit conversion to force displacement of the "this" + -- pointer. + + if Is_Interface (Designated_Type (Acc_Type)) then + Rewrite (Allocator, Convert_To (Acc_Type, Relocate_Node (Allocator))); + end if; + + Analyze_And_Resolve (Allocator, Acc_Type); + end Make_CPP_Constructor_Call_In_Allocator; + ----------------------------------- -- Needs_BIP_Finalization_Master -- ----------------------------------- diff --git a/gcc/ada/exp_ch6.ads b/gcc/ada/exp_ch6.ads index 42ba07d..0f65a5b 100644 --- a/gcc/ada/exp_ch6.ads +++ b/gcc/ada/exp_ch6.ads @@ -205,6 +205,16 @@ package Exp_Ch6 is -- for which Is_Build_In_Place_Call is True, or an N_Qualified_Expression -- node applied to such a function call. + procedure Make_CPP_Constructor_Call_In_Allocator + (Allocator : Node_Id; + Function_Call : Node_Id); + -- Handle a call to a CPP constructor that occurs as the expression that + -- initializes an allocator, by passing access to the allocated object as + -- an additional parameter of the constructor call. A new access object is + -- declared that is initialized to the result of the allocator, passed to + -- the constructor, and the allocator is rewritten to refer to that access + -- object. Function_Call must denote a call to a CPP_Constructor function. + function Needs_BIP_Alloc_Form (Func_Id : Entity_Id) return Boolean; -- Ada 2005 (AI-318-02): Return True if the function needs an implicit -- BIP_Alloc_Form parameter (see type BIP_Formal_Kind).