aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Schonberg <schonberg@adacore.com>2018-07-16 14:12:18 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2018-07-16 14:12:18 +0000
commit4aba11eeb36ea84d768eaaf7d0e2c49742f88cd8 (patch)
treebcc0711d6c266d1a3a035c7dfa25e0e6eaa5d4e8
parentafe9c53918d14a5ef8807ea4284512dd94e4c15d (diff)
downloadgcc-4aba11eeb36ea84d768eaaf7d0e2c49742f88cd8.zip
gcc-4aba11eeb36ea84d768eaaf7d0e2c49742f88cd8.tar.gz
gcc-4aba11eeb36ea84d768eaaf7d0e2c49742f88cd8.tar.bz2
[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
-rw-r--r--gcc/ada/ChangeLog7
-rw-r--r--gcc/ada/exp_ch7.adb47
2 files changed, 46 insertions, 8 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 22fc57b..cea3502 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,5 +1,12 @@
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
deep copy of the left operand when building each conjuct of the
expanded membership operation, to avoid sharing nodes between them.
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index d14cd7e..b1f2b43 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -3994,6 +3994,34 @@ package body Exp_Ch7 is
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
@@ -4002,8 +4030,10 @@ package body Exp_Ch7 is
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;
@@ -4035,17 +4065,18 @@ package body Exp_Ch7 is
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);