]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada: Fix crash on default value with nested iterated component associations
authorEric Botcazou <ebotcazou@adacore.com>
Wed, 16 Oct 2024 07:05:55 +0000 (09:05 +0200)
committerMarc Poulhiès <dkm@gcc.gnu.org>
Mon, 4 Nov 2024 15:57:58 +0000 (16:57 +0100)
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.

gcc/ada/freeze.adb

index 9a862176c30a0aede1cdec61e05fd809f69c013f..7502a04d51751129a5c6a6954475fe7377412753 100644 (file)
@@ -9055,8 +9055,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
@@ -9083,12 +9084,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