]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada: Fix memory leak in expression function returning Big_Integer
authorEric Botcazou <ebotcazou@adacore.com>
Sat, 8 Apr 2023 16:29:16 +0000 (18:29 +0200)
committerMarc Poulhiès <poulhies@adacore.com>
Mon, 29 May 2023 08:23:22 +0000 (10:23 +0200)
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.

gcc/ada/exp_ch7.adb
gcc/ada/sem_res.adb

index 1586e8fbfca8939c7e30f6d5a03150b52118fd37..520bb099d339d43d5ab4959b4bc8613b9dc590aa 100644 (file)
@@ -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
 
index 899b5b5c5220701e4f1f4cfa68a4336c3f7ab4ca..b16e48917f2570772e7c677370def537ce2dc1a2 100644 (file)
@@ -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)));