https://gcc.gnu.org/g:6a64f6c3ebb88a30ee1f36803c48573731018e0c
commit r15-10648-g6a64f6c3ebb88a30ee1f36803c48573731018e0c Author: Eric Botcazou <[email protected]> Date: Sat Jan 3 11:47:35 2026 +0100 Ada: Fix infinite loop on iterated element association with iterator and key Unlike when the key expression is not present, Resolve_Iterated_Association analyzes instead of preanalyzes the iterator specification, which causes the expander to be invoked on an orphaned copy of the iterator expression. gcc/ada/ PR ada/123371 * sem_aggr.adb (Resolve_Iterated_Association): Call Preanalyze instead of Analyze consistently, as well as Copy_Separate_Tree instead of New_Copy_Tree. gcc/testsuite/ * gnat.dg/specs/aggr10.ads: New test. Diff: --- gcc/ada/sem_aggr.adb | 20 +++++++++++--------- gcc/testsuite/gnat.dg/specs/aggr10.ads | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb index c78bed006ec2..736ff2c1fc9d 100644 --- a/gcc/ada/sem_aggr.adb +++ b/gcc/ada/sem_aggr.adb @@ -3826,10 +3826,9 @@ package body Sem_Aggr is -- is present. if Nkind (Comp) = N_Iterated_Element_Association then - -- Create a temporary scope to avoid some modifications from - -- escaping the Analyze call below. The original Tree will be - -- reanalyzed later. + -- escaping the Preanalyze call below. The original tree will + -- be reanalyzed later. Ent := New_Internal_Entity (E_Loop, Current_Scope, Sloc (Comp), 'L'); @@ -3841,8 +3840,7 @@ package body Sem_Aggr is Copy := Copy_Separate_Tree (Comp); Set_Parent (Copy, Parent (Comp)); - Analyze - (Loop_Parameter_Specification (Copy)); + Preanalyze (Loop_Parameter_Specification (Copy)); if Present (Iterator_Specification (Copy)) then Loop_Param_Id := @@ -3853,9 +3851,11 @@ package body Sem_Aggr is end if; Id_Name := Chars (Loop_Param_Id); + else Copy := Copy_Separate_Tree (Iterator_Specification (Comp)); - Analyze (Copy); + + Preanalyze (Copy); Loop_Param_Id := Defining_Identifier (Copy); @@ -3876,17 +3876,19 @@ package body Sem_Aggr is & "(RM22 4.3.5(24))", Comp); else - Preanalyze_And_Resolve (New_Copy_Tree (Key_Expr), Key_Type); + Preanalyze_And_Resolve + (Copy_Separate_Tree (Key_Expr), Key_Type); end if; end if; + End_Scope; Typ := Etype (Loop_Param_Id); elsif Present (Iterator_Specification (Comp)) then -- Create a temporary scope to avoid some modifications from - -- escaping the Analyze call below. The original Tree will be - -- reanalyzed later. + -- escaping the Preanalyze call below. The original tree will + -- be reanalyzed later. Ent := New_Internal_Entity (E_Loop, Current_Scope, Sloc (Comp), 'L'); diff --git a/gcc/testsuite/gnat.dg/specs/aggr10.ads b/gcc/testsuite/gnat.dg/specs/aggr10.ads new file mode 100644 index 000000000000..caa42ff1caad --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/aggr10.ads @@ -0,0 +1,21 @@ +-- PR ada/123371 +-- { dg-do compile } +-- { dg-options "-gnat2022" } + +with Ada.Containers.Ordered_Maps; + +package Aggr10 is + + package Maps is new Ada.Containers.Ordered_Maps (Integer, Integer); + + function F return Maps.Map is ([]); + + A : Maps.Map := [for I of Maps.Map'[] => 1]; -- Works + B : Maps.Map := [for I of A => 1]; -- Works + C : Maps.Map := [for I of B use 1 => 1]; -- Works + D : Maps.Map := [for I of F => 1]; -- Works + + X : Maps.Map := [for I of Maps.Map'[] use 1 => 1]; -- Infinite loop + Y : Maps.Map := [for I of F use 1 => 1]; -- Infinite loop + +end Aggr10;
