aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2023-04-13 23:11:38 +0200
committerMarc Poulhiès <poulhies@adacore.com>2023-05-30 09:12:16 +0200
commit9dbf6adb3e0f849d0622a59b6c722f0d868e6c25 (patch)
tree7e17e2e62e25b5f46a0617ffd1b7355c2fb55610
parent9be806a5c671f9524a92cd610750bf8712bed149 (diff)
downloadgcc-9dbf6adb3e0f849d0622a59b6c722f0d868e6c25.zip
gcc-9dbf6adb3e0f849d0622a59b6c722f0d868e6c25.tar.gz
gcc-9dbf6adb3e0f849d0622a59b6c722f0d868e6c25.tar.bz2
ada: Fix fallout of recent fix for missing finalization
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.
-rw-r--r--gcc/ada/exp_ch7.adb36
1 files changed, 26 insertions, 10 deletions
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index 520bb09..42b41e5 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -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;