From: Eric Botcazou <[email protected]>
The current code does not deal with all the anonymous contexts uniformly,
since it potentially creates an activation chain and a master only in the
case of an actual in a call; moreover, the master is created in the scope
of the actual's type, instead of in the context of the call like the chain.
The change also aligns Make_Build_In_Place_Call_In_Anonymous_Context with
sibling routines by calling Make_Build_In_Place_Call_In_Object_Declaration
directly instead of letting the expander recursively do it. It also adds
a missing rewriting in Make_Build_In_Place_Iface_Call_In_Anonymous_Context.
gcc/ada/ChangeLog:
* exp_ch6.adb (Expand_Actuals): Do not create activation chain and
master for build-in-place calls here but...
(Make_Build_In_Place_Call_In_Allocator): Use Unqual_Conv.
(Make_Build_In_Place_Call_In_Anonymous_Context): ...here instead.
Call Make_Build_In_Place_Call_In_Object_Declaration directly.
(Make_Build_In_Place_Iface_Call_In_Anonymous_Context): ...and here
instead. Add missing rewriting of the call.
Tested on x86_64-pc-linux-gnu, committed on master.
---
gcc/ada/exp_ch6.adb | 57 +++++++++++++++++++++------------------------
1 file changed, 26 insertions(+), 31 deletions(-)
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index b388044fb3c..23150c73b91 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -2729,9 +2729,7 @@ package body Exp_Ch6 is
-- Ada 2005 (AI-318-02): If the actual parameter is a call to a
-- build-in-place function, then a temporary return object needs
- -- to be created and access to it must be passed to the function
- -- (and ensure that we have an activation chain defined for tasks
- -- and a Master variable).
+ -- to be created and access to it must be passed to the function.
-- But do not do it here for intrinsic subprograms since this will
-- be done properly after the subprogram is expanded.
@@ -2740,11 +2738,6 @@ package body Exp_Ch6 is
null;
elsif Is_Build_In_Place_Function_Call (Actual) then
- if Might_Have_Tasks (Etype (Actual)) then
- Build_Activation_Chain_Entity (N);
- Build_Master_Entity (Etype (Actual));
- end if;
-
Make_Build_In_Place_Call_In_Anonymous_Context (Actual);
-- Ada 2005 (AI-318-02): Specialization of the previous case for
@@ -2752,8 +2745,6 @@ package body Exp_Ch6 is
-- object covers interface types.
elsif Present (Unqual_BIP_Iface_Function_Call (Actual)) then
- Build_Activation_Chain_Entity (N);
- Build_Master_Entity (Etype (Actual));
Make_Build_In_Place_Iface_Call_In_Anonymous_Context (Actual);
end if;
@@ -9009,9 +9000,9 @@ package body Exp_Ch6 is
(Allocator : Node_Id;
Function_Call : Node_Id)
is
- Acc_Type : constant Entity_Id := Etype (Allocator);
+ Acc_Type : constant Entity_Id := Etype (Allocator);
Loc : constant Source_Ptr := Sloc (Function_Call);
- Func_Call : Node_Id := Function_Call;
+ Func_Call : constant Node_Id := Unqual_Conv (Function_Call);
Ref_Func_Call : Node_Id;
Function_Id : Entity_Id;
Result_Subt : Entity_Id;
@@ -9024,16 +9015,6 @@ package body Exp_Ch6 is
Chain : Entity_Id; -- activation chain, in case of tasks
begin
- -- Step past qualification or unchecked conversion (the latter can occur
- -- in cases of calls to 'Input).
-
- if Nkind (Func_Call) in N_Qualified_Expression
- | N_Type_Conversion
- | N_Unchecked_Type_Conversion
- then
- Func_Call := Expression (Func_Call);
- end if;
-
-- Mark the call as processed as a build-in-place call
pragma Assert (not Is_Expanded_Build_In_Place_Call (Func_Call));
@@ -9287,6 +9268,7 @@ package body Exp_Ch6 is
Loc : constant Source_Ptr := Sloc (Function_Call);
Func_Call : constant Node_Id := Unqual_Conv (Function_Call);
Function_Id : Entity_Id;
+ Has_Tasks : Boolean;
Known_Size : Boolean;
Needs_Fin : Boolean;
Result_Subt : Entity_Id;
@@ -9315,6 +9297,7 @@ package body Exp_Ch6 is
Warn_BIP (Func_Call);
Result_Subt := Etype (Function_Id);
+ Has_Tasks := Might_Have_Tasks (Result_Subt);
Known_Size := Caller_Known_Size (Func_Call, Result_Subt);
Needs_Fin := Needs_Finalization (Result_Subt);
@@ -9326,15 +9309,11 @@ package body Exp_Ch6 is
-- object also needs to be created and an access value designating it
-- passed as an actual.
- -- Create a temporary which is initialized with the function call:
- --
- -- Temp_Id : Func_Type := BIP_Func_Call;
- --
- -- The initialization expression of the temporary will be rewritten by
- -- the expander using the appropriate mechanism in Make_Build_In_Place_
- -- Call_In_Object_Declaration.
+ -- Insert a temporary before the call initialized with function call to
+ -- reuse the BIP machinery which takes care of adding the extra build-in
+ -- place actuals.
- if Needs_Fin or else Known_Size then
+ if Needs_Fin or else Known_Size or else Has_Tasks then
if Needs_Fin then
Establish_Transient_Scope
(Func_Call, Manage_Sec_Stack => not Known_Size);
@@ -9351,9 +9330,20 @@ package body Exp_Ch6 is
begin
Set_Assignment_OK (Temp_Decl);
+ Expander_Mode_Save_And_Set (False);
Insert_Action (Function_Call, Temp_Decl);
+ Expander_Mode_Restore;
+
+ if Has_Tasks then
+ Build_Activation_Chain_Entity (Temp_Decl);
+ Build_Master_Entity (Temp_Id);
+ end if;
+
+ Make_Build_In_Place_Call_In_Object_Declaration
+ (Obj_Decl => Temp_Decl,
+ Function_Call => Expression (Temp_Decl));
+
Rewrite (Function_Call, New_Occurrence_Of (Temp_Id, Loc));
- Analyze (Function_Call);
end;
-- When the result subtype is unconstrained, the function must allocate
@@ -10034,9 +10024,14 @@ package body Exp_Ch6 is
Insert_Action (Function_Call, Tmp_Decl);
Expander_Mode_Restore;
+ Build_Activation_Chain_Entity (Tmp_Decl);
+ Build_Master_Entity (Tmp_Id);
+
Make_Build_In_Place_Iface_Call_In_Object_Declaration
(Obj_Decl => Tmp_Decl,
Function_Call => Expression (Tmp_Decl));
+
+ Rewrite (Function_Call, New_Occurrence_Of (Tmp_Id, Loc));
end Make_Build_In_Place_Iface_Call_In_Anonymous_Context;
----------------------------------------------------------
--
2.51.0