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