Commit 4aba11ee by Ed Schonberg Committed by Pierre-Marie de Rodat

[Ada] Fix expansion of blocks in loops inside elaboration code

2018-07-16  Ed Schonberg  <schonberg@adacore.com>

gcc/ada/

	* 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.

From-SVN: r262728
parent afe9c539
2018-07-16 Ed Schonberg <schonberg@adacore.com> 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 * exp_ch4.adb (Expand_Set_Membership): Use New_Copy_Tree to perform a
deep copy of the left operand when building each conjuct of the deep copy of the left operand when building each conjuct of the
expanded membership operation, to avoid sharing nodes between them. expanded membership operation, to avoid sharing nodes between them.
......
...@@ -3994,6 +3994,34 @@ package body Exp_Ch7 is ...@@ -3994,6 +3994,34 @@ package body Exp_Ch7 is
Elab_Call : Node_Id; Elab_Call : Node_Id;
Elab_Proc : Entity_Id; Elab_Proc : Entity_Id;
Stat : Node_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 begin
if Unnest_Subprogram_Mode if Unnest_Subprogram_Mode
...@@ -4002,8 +4030,10 @@ package body Exp_Ch7 is ...@@ -4002,8 +4030,10 @@ package body Exp_Ch7 is
then then
Stat := First (Statements (Handled_Statement_Sequence (N))); Stat := First (Statements (Handled_Statement_Sequence (N)));
while Present (Stat) loop while Present (Stat) loop
exit when Nkind (Stat) = N_Block_Statement exit when ((Nkind (Stat) = N_Block_Statement
and then Present (Identifier (Stat)); and then Present (Identifier (Stat)))
or else Nkind (Stat) = N_Loop_Statement)
and then Contains_Subprogram (Entity (Identifier (Stat)));
Next (Stat); Next (Stat);
end loop; end loop;
...@@ -4035,17 +4065,18 @@ package body Exp_Ch7 is ...@@ -4035,17 +4065,18 @@ package body Exp_Ch7 is
Analyze (Elab_Call); Analyze (Elab_Call);
-- The scope of all blocks in the elaboration code is now the -- The scope of all blocks and loops in the elaboration code is
-- constructed elaboration procedure. Nested subprograms within -- now the constructed elaboration procedure. Nested subprograms
-- those blocks will have activation records if they contain -- within those blocks will have activation records if they
-- references to entities in the enclosing block. -- contain references to entities in the enclosing block.
Stat := Stat :=
First (Statements (Handled_Statement_Sequence (Elab_Body))); First (Statements (Handled_Statement_Sequence (Elab_Body)));
while Present (Stat) loop while Present (Stat) loop
if Nkind (Stat) = N_Block_Statement if (Nkind (Stat) = N_Block_Statement
and then Present (Identifier (Stat)) and then Present (Identifier (Stat)))
or else Nkind (Stat) = N_Loop_Statement
then then
Set_Scope (Entity (Identifier (Stat)), Elab_Proc); Set_Scope (Entity (Identifier (Stat)), Elab_Proc);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment