[COMMITTED] ada: Fix memory leak in expression function returning Big_Integer
Commit Message
From: Eric Botcazou <ebotcazou@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(-)
@@ -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
@@ -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)));