From: Eric Botcazou Date: Sat, 8 Apr 2023 16:29:16 +0000 (+0200) Subject: ada: Fix memory leak in expression function returning Big_Integer X-Git-Tag: basepoints/gcc-15~8787 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=61c54dd719630570161551bb52b6e5412fc5f85e;p=thirdparty%2Fgcc.git ada: Fix memory leak in expression function returning Big_Integer 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. --- diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb index 1586e8fbfca8..520bb099d339 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 899b5b5c5220..b16e48917f25 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)));