diff mbox series

[Ada] Unnesting issues with entry families and accept statements

Message ID 20191010152947.GA87637@adacore.com
State New
Headers show
Series [Ada] Unnesting issues with entry families and accept statements | expand

Commit Message

Pierre-Marie de Rodat Oct. 10, 2019, 3:29 p.m. UTC
The case of a protected entry family body with a nested subprogram
wasn't recognized for purposes of unnesting, leading to unhandled
up-level references, because Has_Nested_Subprogram was incorrectly
returning False. This was due to Set_Has_Nested_Subprogram not being
called on the procedure created for the entry body, because
Enclosing_Subprogram wasn't locating any subprogram. That function
needed to be modified to account for the E_Entry_Family case and return
the Protected_Body_Subprogram in that case (as it already did for
E_Entry).

That fix happened to expose another unnesting problem involving selected
accept alternatives containing a nested accept statement, where
references to local temporaries of the nested accept statement were
improperly treated as up-level because their Scope was pointing to the
inner accept statement's entry entity rather than the procedure
generated for the enclosing accept statement. This turned out to be
another case where Reset_Scopes_To needs to be called to reset the Scope
field of local declared entities within the block created for accept
statements.

Tested on x86_64-pc-linux-gnu, committed on trunk

2019-10-10  Gary Dismukes  <dismukes@adacore.com>

gcc/ada/

	* sem_util.adb (Enclosing_Subprogram): Handle the case of
	E_Entry_Family, returning the entry family's associated
	Protected_Body_Subprogram (as was already done for E_Entry).
	* exp_ch9.adb (Expand_N_Accept_Statement): Call Reset_Scopes_To
	on the block created for an accept statement to reset the scopes
	of any local entities to the block scope.
diff mbox series

Patch

--- gcc/ada/exp_ch9.adb
+++ gcc/ada/exp_ch9.adb
@@ -6624,6 +6624,13 @@  package body Exp_Ch9 is
              Declarations               => Declarations (N),
              Handled_Statement_Sequence => Build_Accept_Body (N));
 
+         --  Reset the Scope of local entities associated with the accept
+         --  statement (that currently reference the entry scope) to the
+         --  block scope, to avoid having references to the locals treated
+         --  as up-level references.
+
+         Reset_Scopes_To (Block, Blkent);
+
          --  For the analysis of the generated declarations, the parent node
          --  must be properly set.
 

--- gcc/ada/sem_util.adb
+++ gcc/ada/sem_util.adb
@@ -6997,17 +6997,17 @@  package body Sem_Util is
       elsif Ekind_In (Dyn_Scop, E_Block, E_Loop, E_Return_Statement) then
          return Enclosing_Subprogram (Dyn_Scop);
 
-      elsif Ekind (Dyn_Scop) = E_Entry then
+      elsif Ekind_In (Dyn_Scop, E_Entry, E_Entry_Family) then
 
-         --  For a task entry, return the enclosing subprogram of the
-         --  task itself.
+         --  For a task entry or entry family, return the enclosing subprogram
+         --  of the task itself.
 
          if Ekind (Scope (Dyn_Scop)) = E_Task_Type then
             return Enclosing_Subprogram (Dyn_Scop);
 
-         --  A protected entry is rewritten as a protected procedure which is
-         --  the desired enclosing subprogram. This is relevant when unnesting
-         --  a procedure local to an entry body.
+         --  A protected entry or entry family is rewritten as a protected
+         --  procedure which is the desired enclosing subprogram. This is
+         --  relevant when unnesting a procedure local to an entry body.
 
          else
             return Protected_Body_Subprogram (Dyn_Scop);