From: Eric Botcazou <ebotca...@adacore.com>

The finalization machinery needs to precisely locate the point where the
initialization of objects is complete in order to generate the attachment
to the finalization master.  For objects initialized with a built-in-place
function call, this is achieved by means of the BIP_Initialization_Call
field present in their entity node, but this field is only set in the case
where the enclosing scope is transient, which is not guaranteed.

gcc/ada/ChangeLog:

        * einfo.ads (BIP_Initialization_Call): Adjust description.
        * exp_ch4.adb (Expand_N_Case_Expression): Adjust commentary.
        (Expand_N_If_Expression): Likewise.
        * exp_ch6.adb (Make_Build_In_Place_Call_In_Object_Declaration):
        Set BIP_Initialization_Call unconditionally in the definite case.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/einfo.ads   |  7 +++----
 gcc/ada/exp_ch4.adb | 21 ++++++++++++---------
 gcc/ada/exp_ch6.adb | 20 +++++---------------
 3 files changed, 20 insertions(+), 28 deletions(-)

diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
index 025465265f3..d283358c0c0 100644
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -526,12 +526,11 @@ package Einfo is
 --       references on this list are illegal due to the visible refinement.
 
 --    BIP_Initialization_Call
---       Defined in constants and variables whose corresponding declaration
---       is wrapped in a transient block and the inital value is provided by
+--       Defined in constants and variables whose initial value is provided by
 --       a build-in-place function call. Contains the relocated build-in-place
 --       call after the expansion has decoupled the call from the object. This
---       attribute is used by the finalization machinery to insert cleanup code
---       for all additional transient objects found in the transient block.
+--       attribute is used by the finalization machinery to insert the call to
+--       the routine that attaches the object to the finalization master.
 
 --    C_Pass_By_Copy [implementation base type only]
 --       Defined in record types. Set if a pragma Convention for the record
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index f44f21d654b..81b2b734bbf 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -5104,7 +5104,8 @@ package body Exp_Ch4 is
       --  If the expression is in the context of a simple return statement,
       --  possibly through intermediate conditional expressions, we delay
       --  expansion until the (immediate) parent is rewritten as a return
-      --  statement (or is already the return statement).
+      --  statement (or is already the return statement). Likewise if it is
+      --  in the context of an object declaration that can be optimized.
 
       if not Expansion_Delayed (N) then
          declare
@@ -5119,9 +5120,9 @@ package body Exp_Ch4 is
       end if;
 
       --  If the expansion of the expression has been delayed, we wait for the
-      --  rewriting of its parent as an assignment or return statement; when
-      --  that's done, we optimize the assignment or the return statement (the
-      --  very purpose of the manipulation).
+      --  rewriting of its parent as an assignment statement, or as as return
+      --  statement or as an object declaration; when that's done, we optimize
+      --  the assignment, return or declaration (the purpose of the delaying).
 
       if Expansion_Delayed (N) then
          if Nkind (Par) = N_Assignment_Statement then
@@ -5721,8 +5722,10 @@ package body Exp_Ch4 is
       --  If the expression is in the context of a simple return statement,
       --  possibly through intermediate conditional expressions, we delay
       --  expansion until the (immediate) parent is rewritten as a return
-      --  statement (or is already the return statement). Note that this
-      --  deals with the case of the elsif part of the if expression.
+      --  statement (or is already the return statement). Likewise if it is
+      --  in the context of an object declaration that can be optimized.
+      --  Note that this deals with the case of the elsif part of the if
+      --  expression, if it exists.
 
       if not Expansion_Delayed (N) then
          declare
@@ -5737,9 +5740,9 @@ package body Exp_Ch4 is
       end if;
 
       --  If the expansion of the expression has been delayed, we wait for the
-      --  rewriting of its parent as an assignment or return statement; when
-      --  that's done, we optimize the assignment or the return statement (the
-      --  very purpose of the manipulation).
+      --  rewriting of its parent as an assignment statement, or as as return
+      --  statement or as an object declaration; when that's done, we optimize
+      --  the assignment, return or declaration (the purpose of the delaying).
 
       if Expansion_Delayed (N) then
          if Nkind (Par) = N_Assignment_Statement then
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index ef5faa1e34e..c65ea91cb13 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -9115,24 +9115,14 @@ package body Exp_Ch6 is
 
       if Definite and then not Is_OK_Return_Object then
 
-         --  The related object declaration is encased in a transient block
-         --  because the build-in-place function call contains at least one
-         --  nested function call that produces a controlled transient
-         --  temporary:
-
-         --    Obj : ... := BIP_Func_Call (Ctrl_Func_Call);
+         Set_Expression (Obj_Decl, Empty);
+         Set_No_Initialization (Obj_Decl);
 
          --  Since the build-in-place expansion decouples the call from the
-         --  object declaration, the finalization machinery lacks the context
-         --  which prompted the generation of the transient block. To resolve
-         --  this scenario, store the build-in-place call.
+         --  object declaration, the finalization machinery needs to know
+         --  when the object is initialized. Store the build-in-place call.
 
-         if Scope_Is_Transient then
-            Set_BIP_Initialization_Call (Obj_Def_Id, Res_Decl);
-         end if;
-
-         Set_Expression (Obj_Decl, Empty);
-         Set_No_Initialization (Obj_Decl);
+         Set_BIP_Initialization_Call (Obj_Def_Id, Res_Decl);
 
          --  Park the generated statements if the declaration requires it and
          --  is not the node that is wrapped in a transient scope.
-- 
2.43.0

Reply via email to