[COMMITTED] ada: Fix fallout of recent fix for missing finalization
Checks
Commit Message
From: Eric Botcazou <ebotcazou@adacore.com>
The original fix makes it possible to create transient scopes around return
statements in more cases, but it overlooks that transient scopes are reused
and, in particular, that they can be promoted to secondary stack management.
gcc/ada/
* exp_ch7.adb (Find_Enclosing_Transient_Scope): Return the index in
the scope table instead of the scope's entity.
(Establish_Transient_Scope): If an enclosing scope already exists,
do not set the Uses_Sec_Stack flag on it if the node to be wrapped
is a return statement which requires secondary stack management.
Tested on x86_64-pc-linux-gnu, committed on master.
---
gcc/ada/exp_ch7.adb | 36 ++++++++++++++++++++++++++----------
1 file changed, 26 insertions(+), 10 deletions(-)
@@ -4476,10 +4476,10 @@ package body Exp_Ch7 is
function Is_Package_Or_Subprogram (Id : Entity_Id) return Boolean;
-- Determine whether arbitrary Id denotes a package or subprogram [body]
- function Find_Enclosing_Transient_Scope return Entity_Id;
+ function Find_Enclosing_Transient_Scope return Int;
-- Examine the scope stack looking for the nearest enclosing transient
-- scope within the innermost enclosing package or subprogram. Return
- -- Empty if no such scope exists.
+ -- its index in the table or else -1 if no such scope exists.
function Find_Transient_Context (N : Node_Id) return Node_Id;
-- Locate a suitable context for arbitrary node N which may need to be
@@ -4605,7 +4605,7 @@ package body Exp_Ch7 is
-- Find_Enclosing_Transient_Scope --
------------------------------------
- function Find_Enclosing_Transient_Scope return Entity_Id is
+ function Find_Enclosing_Transient_Scope return Int is
begin
for Index in reverse Scope_Stack.First .. Scope_Stack.Last loop
declare
@@ -4620,12 +4620,12 @@ package body Exp_Ch7 is
exit;
elsif Scope.Is_Transient then
- return Scope.Entity;
+ return Index;
end if;
end;
end loop;
- return Empty;
+ return -1;
end Find_Enclosing_Transient_Scope;
----------------------------
@@ -4822,8 +4822,8 @@ package body Exp_Ch7 is
-- Local variables
- Trans_Id : constant Entity_Id := Find_Enclosing_Transient_Scope;
- Context : Node_Id;
+ Trans_Idx : constant Int := Find_Enclosing_Transient_Scope;
+ Context : Node_Id;
-- Start of processing for Establish_Transient_Scope
@@ -4831,13 +4831,29 @@ package body Exp_Ch7 is
-- Do not create a new transient scope if there is already an enclosing
-- transient scope within the innermost enclosing package or subprogram.
- if Present (Trans_Id) then
+ if Trans_Idx >= 0 then
-- If the transient scope was requested for purposes of managing the
- -- secondary stack, then the existing scope must perform this task.
+ -- secondary stack, then the existing scope must perform this task,
+ -- unless the node to be wrapped is a return statement of a function
+ -- that requires secondary stack management, because the function's
+ -- result would be reclaimed too early (see Find_Transient_Context).
if Manage_Sec_Stack then
- Set_Uses_Sec_Stack (Trans_Id);
+ declare
+ SE : Scope_Stack_Entry renames Scope_Stack.Table (Trans_Idx);
+
+ begin
+ if Nkind (SE.Node_To_Be_Wrapped) /= N_Simple_Return_Statement
+ or else not
+ Needs_Secondary_Stack
+ (Etype
+ (Return_Applies_To
+ (Return_Statement_Entity (SE.Node_To_Be_Wrapped))))
+ then
+ Set_Uses_Sec_Stack (SE.Entity);
+ end if;
+ end;
end if;
return;