aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/exp_ch7.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/exp_ch7.adb')
-rw-r--r--gcc/ada/exp_ch7.adb87
1 files changed, 56 insertions, 31 deletions
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index 62e9d2c..600d333 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -4758,18 +4758,18 @@ package body Exp_Ch7 is
-- We mark the secondary stack if it is used in this construct, and
-- we're not returning a function result on the secondary stack, except
- -- that a build-in-place function that might or might not return on the
- -- secondary stack always needs a mark. A run-time test is required in
- -- the case where the build-in-place function has a BIP_Alloc extra
- -- parameter (see Create_Finalizer).
+ -- that a build-in-place function that only conditionally returns on
+ -- the secondary stack will also need a mark. A run-time test for doing
+ -- the release call is needed in the case where the build-in-place
+ -- function has a BIP_Alloc_Form parameter (see Create_Finalizer).
Needs_Sec_Stack_Mark : constant Boolean :=
- (Uses_Sec_Stack (Scop)
- and then
- not Sec_Stack_Needed_For_Return (Scop))
- or else
- (Is_Build_In_Place_Function (Scop)
- and then Needs_BIP_Alloc_Form (Scop));
+ Uses_Sec_Stack (Scop)
+ and then
+ (not Sec_Stack_Needed_For_Return (Scop)
+ or else
+ (Is_Build_In_Place_Function (Scop)
+ and then Needs_BIP_Alloc_Form (Scop)));
Needs_Custom_Cleanup : constant Boolean :=
Nkind (N) = N_Block_Statement
@@ -9244,7 +9244,7 @@ package body Exp_Ch7 is
procedure Unnest_Loop (Loop_Stmt : Node_Id) is
- procedure Fixup_Inner_Scopes (Loop_Or_Block : Node_Id);
+ procedure Fixup_Inner_Scopes (N : Node_Id);
-- This procedure fixes the scope for 2 identified cases of incorrect
-- scope information.
--
@@ -9271,6 +9271,9 @@ package body Exp_Ch7 is
-- leaves the Tree in an incoherent state (i.e. the inner procedure must
-- have its enclosing procedure in its scope ancestries).
+ -- The same issue exists for freeze nodes with associated TSS: the node
+ -- is moved but the TSS procedures are not correctly nested.
+
-- 2) The second case happens when an object declaration is created
-- within a loop used to initialize the 'others' components of an
-- aggregate that is nested within a transient scope. When the transient
@@ -9298,40 +9301,62 @@ package body Exp_Ch7 is
-- an actual entity set). But unfortunately this proved harder to
-- implement ???
- procedure Fixup_Inner_Scopes (Loop_Or_Block : Node_Id) is
- Stmt : Node_Id;
- Loop_Or_Block_Ent : Entity_Id;
- Ent_To_Fix : Entity_Id;
- Decl : Node_Id := Empty;
+ procedure Fixup_Inner_Scopes (N : Node_Id) is
+ Stmt : Node_Id := Empty;
+ Ent : Entity_Id;
+ Ent_To_Fix : Entity_Id;
+ Decl : Node_Id := Empty;
+ Elmt : Elmt_Id := No_Elmt;
begin
- pragma Assert (Nkind (Loop_Or_Block) in
- N_Loop_Statement | N_Block_Statement);
-
- Loop_Or_Block_Ent := Entity (Identifier (Loop_Or_Block));
- if Nkind (Loop_Or_Block) = N_Loop_Statement then
- Stmt := First (Statements (Loop_Or_Block));
- else -- N_Block_Statement
- Stmt := First
- (Statements (Handled_Statement_Sequence (Loop_Or_Block)));
- Decl := First (Declarations (Loop_Or_Block));
+ pragma
+ Assert
+ (Nkind (N)
+ in N_Loop_Statement | N_Block_Statement | N_Freeze_Entity);
+
+ if Nkind (N) = N_Freeze_Entity then
+ Ent := Scope (Entity (N));
+ else
+ Ent := Entity (Identifier (N));
end if;
+ case Nkind (N) is
+ when N_Loop_Statement =>
+ Stmt := First (Statements (N));
+
+ when N_Block_Statement =>
+ Stmt := First (Statements (Handled_Statement_Sequence (N)));
+ Decl := First (Declarations (N));
+
+ when N_Freeze_Entity =>
+ if Present (TSS_Elist (N)) then
+ Elmt := First_Elmt (TSS_Elist (N));
+ while Present (Elmt) loop
+ Ent_To_Fix := Node (Elmt);
+ Set_Scope (Ent_To_Fix, Ent);
+ Next_Elmt (Elmt);
+ end loop;
+ end if;
+
+ when others =>
+ pragma Assert (False);
+ end case;
+
-- Fix scopes for any object declaration found in the block
while Present (Decl) loop
if Nkind (Decl) = N_Object_Declaration then
Ent_To_Fix := Defining_Identifier (Decl);
- Set_Scope (Ent_To_Fix, Loop_Or_Block_Ent);
+ Set_Scope (Ent_To_Fix, Ent);
end if;
Next (Decl);
end loop;
while Present (Stmt) loop
- if Nkind (Stmt) = N_Block_Statement
- and then Is_Abort_Block (Stmt)
+ if Nkind (Stmt) = N_Block_Statement and then Is_Abort_Block (Stmt)
then
Ent_To_Fix := Entity (Identifier (Stmt));
- Set_Scope (Ent_To_Fix, Loop_Or_Block_Ent);
- elsif Nkind (Stmt) in N_Block_Statement | N_Loop_Statement
+ Set_Scope (Ent_To_Fix, Ent);
+ elsif Nkind (Stmt)
+ in N_Block_Statement | N_Loop_Statement | N_Freeze_Entity
then
Fixup_Inner_Scopes (Stmt);
end if;