From: Eric Botcazou <ebotca...@adacore.com> We fail to establish a transient scope around the return statement because the function returns a controlled type, but this is no longer problematic because controlled types are no longer returned on the secondary stack.
gcc/ada/ * exp_ch7.adb (Establish_Transient_Scope.Find_Transient_Context): Bail out for a simple return statement only if the transient scope and the function both require secondary stack management, or else if the function is a thunk. * sem_res.adb (Resolve_Call): Do not create a transient scope when the call is the expression of a simple return statement. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/exp_ch7.adb | 32 ++++++++++++++++++++------------ gcc/ada/sem_res.adb | 12 ++++++++---- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb index 1586e8fbfca..520bb099d33 100644 --- a/gcc/ada/exp_ch7.adb +++ b/gcc/ada/exp_ch7.adb @@ -4717,21 +4717,29 @@ package body Exp_Ch7 is return Curr; when N_Simple_Return_Statement => + declare + Fun_Id : constant Entity_Id := + Return_Applies_To (Return_Statement_Entity (Curr)); - -- A return statement is not a valid transient context when - -- the function itself requires transient scope management - -- because the result will be reclaimed too early. - - if Requires_Transient_Scope (Etype - (Return_Applies_To (Return_Statement_Entity (Curr)))) - then - return Empty; + begin + -- A transient context that must manage the secondary + -- stack cannot be a return statement of a function that + -- itself requires secondary stack management, because + -- the function's result would be reclaimed too early. + -- And returns of thunks never require transient scopes. + + if (Manage_Sec_Stack + and then Needs_Secondary_Stack (Etype (Fun_Id))) + or else Is_Thunk (Fun_Id) + then + return Empty; - -- General case for return statements + -- General case for return statements - else - return Curr; - end if; + else + return Curr; + end if; + end; -- Special diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb index 899b5b5c522..b16e48917f2 100644 --- a/gcc/ada/sem_res.adb +++ b/gcc/ada/sem_res.adb @@ -6960,6 +6960,12 @@ package body Sem_Res is -- want to create a transient scope (this could occur in the case of a -- static string-returning call). + -- h) If the subprogram is an ignored ghost entity, because it does not + -- return anything. + + -- i) If the call is the expression of a simple return statement, since + -- it will be handled as a tail call by Expand_Simple_Function_Return. + if Is_Inlined (Nam) and then Has_Pragma_Inline (Nam) and then Nkind (Unit_Declaration_Node (Nam)) = N_Subprogram_Declaration @@ -6972,16 +6978,14 @@ package body Sem_Res is or else Is_Intrinsic_Subprogram (Nam) or else Is_Inlinable_Expression_Function (Nam) or else Is_Static_Function_Call (N) + or else Is_Ignored_Ghost_Entity (Nam) + or else Nkind (Parent (N)) = N_Simple_Return_Statement then null; - -- A return statement from an ignored Ghost function does not use the - -- secondary stack (or any other one). - elsif Expander_Active and then Ekind (Nam) in E_Function | E_Subprogram_Type and then Requires_Transient_Scope (Etype (Nam)) - and then not Is_Ignored_Ghost_Entity (Nam) then Establish_Transient_Scope (N, Needs_Secondary_Stack (Etype (Nam))); -- 2.40.0