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

Reply via email to