https://gcc.gnu.org/g:0a6736ef366af6bcd7e25567919202fd6c40b7c9
commit r15-6534-g0a6736ef366af6bcd7e25567919202fd6c40b7c9 Author: Eric Botcazou <ebotca...@adacore.com> Date: Thu Dec 5 11:15:10 2024 +0100 ada: Fix latent issue exposed by latest change 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. Diff: --- 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 025465265f3c..d283358c0c0e 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 f44f21d654bb..81b2b734bbf0 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 ef5faa1e34e3..c65ea91cb13b 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.