https://gcc.gnu.org/g:eb929c391fe1e6c2e343abbf9464210554da415b

commit r14-10879-geb929c391fe1e6c2e343abbf9464210554da415b
Author: Eric Botcazou <ebotca...@adacore.com>
Date:   Wed Oct 16 09:05:55 2024 +0200

    ada: Fix crash on default value with nested iterated component associations
    
    The problem is that the freeze node for the type of the element ends up in
    the component list of the record type declared with the default value.
    
    gcc/ada/ChangeLog:
    
            PR ada/113036
            * freeze.adb (Freeze_Expression): Deal with freezing actions coming
            from within nested internal loops present in spec expressions.

Diff:
---
 gcc/ada/freeze.adb | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 4c3c45d79752..6da4460c1301 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -8684,8 +8684,9 @@ package body Freeze is
         or else Ekind (Current_Scope) = E_Void
       then
          declare
-            Freeze_Nodes : List_Id := No_List;
-            Pos          : Int     := Scope_Stack.Last;
+            Freeze_Nodes : List_Id   := No_List;
+            Pos          : Int       := Scope_Stack.Last;
+            Scop         : Entity_Id := Current_Scope;
 
          begin
             if Present (Desig_Typ) then
@@ -8712,12 +8713,18 @@ package body Freeze is
             --  If the expression is within a top-level pragma, as for a pre-
             --  condition on a library-level subprogram, nothing to do.
 
-            if not Is_Compilation_Unit (Current_Scope)
-              and then (Is_Record_Type (Scope (Current_Scope))
-                         or else (Ekind (Current_Scope) in E_Block | E_Loop
-                                   and then Is_Internal (Current_Scope)))
-            then
-               Pos := Pos - 1;
+            if not Is_Compilation_Unit (Scop) then
+               if Is_Record_Type (Scope (Scop)) then
+                  Pos := Pos - 1;
+
+               else
+                  while Ekind (Scop) in E_Block | E_Loop
+                    and then Is_Internal (Scop)
+                  loop
+                     Pos  := Pos - 1;
+                     Scop := Scope (Scop);
+                  end loop;
+               end if;
             end if;
 
             if Is_Non_Empty_List (Freeze_Nodes) then

Reply via email to