From: Piotr Trojanek <troja...@adacore.com>

Fix a number of problems in handling of actions generated for a
2-dimensional array aggregate where the outer aggregate has iterated
component association and the inner aggregate involves run-time checks.

gcc/ada/

        * exp_aggr.adb (Add_Loop_Actions): Actions are now attached to
        iterated component association just like they are attached to
        ordinary component association.
        (Build_Array_Aggr_Code): If resolution of the array aggregate
        generated some actions, e.g. for run-time checks, then we must
        keep them; same for the Other_Clause.
        * sem_aggr.adb (Resolve_Iterated_Component_Association): Unset
        references to iterator variable in loop actions (which might come
        from run-time check), just these references are unset in the
        expression itself.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_aggr.adb | 14 +++++++++++---
 gcc/ada/sem_aggr.adb |  9 +++++++++
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 8496fcd9b00..aa6079d82b5 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -1259,7 +1259,8 @@ package body Exp_Aggr is
             if No (Expr) then
                return Lis;
 
-            elsif Nkind (Parent (Expr)) = N_Component_Association
+            elsif Nkind (Parent (Expr)) in N_Component_Association
+                                         | N_Iterated_Component_Association
               and then Present (Loop_Actions (Parent (Expr)))
             then
                Res := Loop_Actions (Parent (Expr));
@@ -1962,7 +1963,9 @@ package body Exp_Aggr is
 
                Bounds := Get_Index_Bounds (Choice);
 
-               if Low /= High then
+               if Low /= High
+                 and then No (Loop_Actions (Assoc))
+               then
                   Set_Loop_Actions (Assoc, New_List);
                end if;
 
@@ -2038,7 +2041,12 @@ package body Exp_Aggr is
 
                   if First or else not Empty_Range (Low, High) then
                      First := False;
-                     Set_Loop_Actions (Others_Assoc, New_List);
+                     if Present (Loop_Actions (Others_Assoc)) then
+                        pragma Assert
+                          (Is_Empty_List (Loop_Actions (Others_Assoc)));
+                     else
+                        Set_Loop_Actions (Others_Assoc, New_List);
+                     end if;
                      Expr := Get_Assoc_Expr (Others_Assoc);
                      Append_List (Gen_Loop (Low, High, Expr), To => New_Code);
                   end if;
diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
index 656d789de73..087e324b5c1 100644
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -2212,6 +2212,15 @@ package body Sem_Aggr is
 
          if Operating_Mode /= Check_Semantics then
             Remove_References (Expr);
+            declare
+               Loop_Action : Node_Id;
+            begin
+               Loop_Action := First (Loop_Actions (N));
+               while Present (Loop_Action) loop
+                  Remove_References (Loop_Action);
+                  Next (Loop_Action);
+               end loop;
+            end;
          end if;
 
          --  An iterated_component_association may appear in a nested
-- 
2.45.2

Reply via email to