diff options
author | Ed Schonberg <schonberg@adacore.com> | 2018-07-16 14:12:18 +0000 |
---|---|---|
committer | Pierre-Marie de Rodat <pmderodat@gcc.gnu.org> | 2018-07-16 14:12:18 +0000 |
commit | 4aba11eeb36ea84d768eaaf7d0e2c49742f88cd8 (patch) | |
tree | bcc0711d6c266d1a3a035c7dfa25e0e6eaa5d4e8 | |
parent | afe9c53918d14a5ef8807ea4284512dd94e4c15d (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/ada/exp_ch7.adb | 47 |
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); |