+2018-07-16 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch7.adb (Check_Unnesting_Elaboration_Code): Handle loops that
+ contain blocks in the elaboration code for a package body. Create the
+ elaboration subprogram wrapper only if there is a subprogram
+ declaration in a block or loop.
+
2018-07-16 Ed Schonberg <schonberg@adacore.com>
* exp_ch4.adb (Expand_Set_Membership): Use New_Copy_Tree to perform a
Elab_Call : Node_Id;
Elab_Proc : Entity_Id;
Stat : Node_Id;
+ function Contains_Subprogram (Blk : Entity_Id) return Boolean;
+ -- Check recursively whether a loop or block contains a subprogram
+ -- that may need an activation record.
+
+ --------------------------
+ -- Contains_Subprogram --
+ --------------------------
+
+ function Contains_Subprogram (Blk : Entity_Id) return Boolean is
+ E : Entity_Id;
+ begin
+ E := First_Entity (Blk);
+
+ while Present (E) loop
+ if Is_Subprogram (E) then
+ return True;
+
+ elsif Ekind_In (E, E_Block, E_Loop)
+ and then Contains_Subprogram (E)
+ then
+ return True;
+ end if;
+
+ Next_Entity (E);
+ end loop;
+
+ return False;
+ end Contains_Subprogram;
begin
if Unnest_Subprogram_Mode
then
Stat := First (Statements (Handled_Statement_Sequence (N)));
while Present (Stat) loop
- exit when Nkind (Stat) = N_Block_Statement
- and then Present (Identifier (Stat));
+ exit when ((Nkind (Stat) = N_Block_Statement
+ and then Present (Identifier (Stat)))
+ or else Nkind (Stat) = N_Loop_Statement)
+ and then Contains_Subprogram (Entity (Identifier (Stat)));
Next (Stat);
end loop;
Analyze (Elab_Call);
- -- The scope of all blocks in the elaboration code is now the
- -- constructed elaboration procedure. Nested subprograms within
- -- those blocks will have activation records if they contain
- -- references to entities in the enclosing block.
+ -- The scope of all blocks and loops in the elaboration code is
+ -- now the constructed elaboration procedure. Nested subprograms
+ -- within those blocks will have activation records if they
+ -- contain references to entities in the enclosing block.
Stat :=
First (Statements (Handled_Statement_Sequence (Elab_Body)));
while Present (Stat) loop
- if Nkind (Stat) = N_Block_Statement
- and then Present (Identifier (Stat))
+ if (Nkind (Stat) = N_Block_Statement
+ and then Present (Identifier (Stat)))
+ or else Nkind (Stat) = N_Loop_Statement
then
Set_Scope (Entity (Identifier (Stat)), Elab_Proc);