https://gcc.gnu.org/g:60b352cd6608727a6c24a2cb1b08b3159a865637

commit r13-9096-g60b352cd6608727a6c24a2cb1b08b3159a865637
Author: Eric Botcazou <ebotca...@adacore.com>
Date:   Thu Sep 5 00:19:25 2024 +0200

    ada: Fix wrong finalization of anonymous array aggregate
    
    The issue arises when the aggregate consists only of iterated associations
    because, in this case, its expansion uses a 2-pass mechanism which creates
    a temporary that needs a fully-fledged initialization, thus running afoul
    of the optimization that avoids building the initialization procedure in
    the anonymous array case.
    
    gcc/ada/ChangeLog:
            * exp_aggr.ads (Is_Two_Pass_Aggregate): New function declaration.
            * exp_aggr.adb (Is_Two_Pass_Aggregate): New function body.
            (Expand_Array_Aggregate): Call Is_Two_Pass_Aggregate to detect the
            aggregates that need the 2-pass expansion.
            * exp_ch3.adb (Expand_Freeze_Array_Type): In the anonymous array
            case, build the initialization procedure if the initial value in
            the object declaration is a 2-pass aggregate.

Diff:
---
 gcc/ada/exp_aggr.adb | 22 ++++++++++++++++------
 gcc/ada/exp_aggr.ads |  4 ++++
 gcc/ada/exp_ch3.adb  | 15 ++++++++++-----
 3 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 306f17bb5bfa..bb58613128b8 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -6684,12 +6684,7 @@ package body Exp_Aggr is
       then
          return;
 
-      elsif Present (Component_Associations (N))
-        and then Nkind (First (Component_Associations (N))) =
-                 N_Iterated_Component_Association
-        and then
-          Present (Iterator_Specification (First (Component_Associations (N))))
-      then
+      elsif Is_Two_Pass_Aggregate (N) then
          Two_Pass_Aggregate_Expansion (N);
          return;
 
@@ -9227,6 +9222,21 @@ package body Exp_Aggr is
         and then C in Uint_1 | Uint_2 | Uint_4; -- False if No_Uint
    end Is_Two_Dim_Packed_Array;
 
+   ---------------------------
+   -- Is_Two_Pass_Aggregate --
+   ---------------------------
+
+   function Is_Two_Pass_Aggregate (N : Node_Id) return Boolean is
+   begin
+      return Nkind (N) = N_Aggregate
+        and then Present (Component_Associations (N))
+        and then Nkind (First (Component_Associations (N))) =
+                   N_Iterated_Component_Association
+        and then
+          Present
+            (Iterator_Specification (First (Component_Associations (N))));
+   end Is_Two_Pass_Aggregate;
+
    --------------------
    -- Late_Expansion --
    --------------------
diff --git a/gcc/ada/exp_aggr.ads b/gcc/ada/exp_aggr.ads
index 4babf2ec54c3..00591aedc6bb 100644
--- a/gcc/ada/exp_aggr.ads
+++ b/gcc/ada/exp_aggr.ads
@@ -35,6 +35,10 @@ package Exp_Aggr is
    --  Returns True if N is an aggregate of some kind whose Expansion_Delayed
    --  flag is set (see sinfo for meaning of flag).
 
+   function Is_Two_Pass_Aggregate (N : Node_Id) return Boolean;
+   --  Return True if N is an aggregate that is to be expanded in two passes.
+   --  This is the case if it consists only of iterated associations.
+
    procedure Convert_Aggr_In_Object_Decl (N : Node_Id);
    --  N is a N_Object_Declaration with an expression which must be an
    --  N_Aggregate or N_Extension_Aggregate with Expansion_Delayed.
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 715f87fc796d..cfc2970a5f77 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -4896,17 +4896,22 @@ package body Exp_Ch3 is
 
          if No (Init_Proc (Base)) then
 
-            --  If this is an anonymous array created for a declaration with
-            --  an initial value, its init_proc will never be called. The
+            --  If this is an anonymous array built for an object declaration
+            --  with an initial value, its Init_Proc will never be called. The
             --  initial value itself may have been expanded into assignments,
-            --  in which case the object declaration is carries the
-            --  No_Initialization flag.
+            --  in which case the declaration has the No_Initialization flag.
+            --  The exception is when the initial value is a 2-pass aggregate,
+            --  because the special expansion used for it creates a temporary
+            --  that needs a fully-fledged initialization.
 
             if Is_Itype (Base)
               and then Nkind (Associated_Node_For_Itype (Base)) =
                                                     N_Object_Declaration
               and then
-                (Present (Expression (Associated_Node_For_Itype (Base)))
+                ((Present (Expression (Associated_Node_For_Itype (Base)))
+                    and then not
+                      Is_Two_Pass_Aggregate
+                        (Expression (Associated_Node_For_Itype (Base))))
                   or else No_Initialization (Associated_Node_For_Itype (Base)))
             then
                null;

Reply via email to