From: Eric Botcazou <[email protected]>
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