diff mbox series

[COMMITTED,29/38] ada: Fix crash on default value with nested iterated component associations

Message ID 20241104161116.1431659-29-poulhies@adacore.com
State New
Headers show
Series [COMMITTED,01/38] ada: Fix asymmetry in resolution of unary intrinsic operators | expand

Commit Message

Marc Poulhiès Nov. 4, 2024, 4:11 p.m. UTC
From: Eric Botcazou <ebotcazou@adacore.com>

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.

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

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

Patch

diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 9a862176c30..7502a04d517 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -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