]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[Ada] Fix iterated component association for array aggregate
authorMarc Poulhiès <poulhies@adacore.com>
Fri, 18 Feb 2022 15:35:06 +0000 (16:35 +0100)
committerPierre-Marie de Rodat <derodat@adacore.com>
Fri, 13 May 2022 08:04:42 +0000 (08:04 +0000)
Create a scope for the Ada 2022 iterated component association loops. In
the case of elements needing finalization, the late expansion would
crash on references to the loop variable within the loop body.

gcc/ada/

* exp_aggr.adb (Gen_Loop): Create scope for loop variable of
iterated components.

gcc/ada/exp_aggr.adb

index 939d091e065defc2e5e1ee381d61ee6cd17a491f..72f65555681ea711e5e6d23a352bace4e2b291b1 100644 (file)
@@ -1916,6 +1916,8 @@ package body Exp_Aggr is
          Is_Iterated_Component : constant Boolean :=
            Parent_Kind (Expr) = N_Iterated_Component_Association;
 
+         Ent : Entity_Id;
+
          L_J : Node_Id;
 
          L_L : Node_Id;
@@ -2025,10 +2027,28 @@ package body Exp_Aggr is
          --  Otherwise construct the loop, starting with the loop index L_J
 
          if Is_Iterated_Component then
+
+            --  Create a new scope for the loop variable so that the
+            --  following Gen_Assign (that ends up calling
+            --  Preanalyze_And_Resolve) can correctly find it.
+
+            Ent := New_Internal_Entity (E_Loop,
+                 Current_Scope, Loc, 'L');
+            Set_Etype  (Ent, Standard_Void_Type);
+            Set_Parent (Ent, Parent (Parent (Expr)));
+            Push_Scope (Ent);
+
             L_J :=
               Make_Defining_Identifier (Loc,
                 Chars => (Chars (Defining_Identifier (Parent (Expr)))));
 
+            Enter_Name (L_J);
+
+            --  The Etype will be set by a later Analyze call.
+            Set_Etype (L_J, Any_Type);
+
+            Mutate_Ekind (L_J, E_Variable);
+            Set_Scope (L_J, Ent);
          else
             L_J := Make_Temporary (Loc, 'J', L);
          end if;
@@ -2083,6 +2103,10 @@ package body Exp_Aggr is
               Iteration_Scheme => L_Iteration_Scheme,
               Statements       => L_Body));
 
+         if Is_Iterated_Component then
+            End_Scope;
+         end if;
+
          --  A small optimization: if the aggregate is initialized with a box
          --  and the component type has no initialization procedure, remove the
          --  useless empty loop.