[COMMITTED,13/31] ada: Fix internal error on container aggregate for bounded vectors

Message ID 20250107125350.619654-13-poulhies@adacore.com
State New
Headers
Series [COMMITTED,01/31] ada: Restrict previous change made to expansion of allocators |

Commit Message

Marc Poulhiès Jan. 7, 2025, 12:53 p.m. UTC
  From: Eric Botcazou <ebotcazou@adacore.com>

The problem is that we analyze references to an object before the actual
subtype of the object is established, thus creating a type mismatch that
is flagged by the code generator.

gcc/ada/ChangeLog:

	* exp_ch7.ads (Store_After_Actions_In_Scope_Without_Analysis): New
	procedure declaration.
	* exp_ch7.adb (Store_New_Actions_In_Scope): New procedure.
	(Store_Actions_In_Scope): Call Store_New_Actions_In_Scope when the
	target list is empty.
	(Store_After_Actions_In_Scope_Without_Analysis): New procedure body.
	* exp_aggr.adb (Expand_Container_Aggregate): For a declaration that
	is wrapped in a transient scope, also defer the analysis of the new
	code until after the declaration is analyzed.

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

---
 gcc/ada/exp_aggr.adb |  9 +++----
 gcc/ada/exp_ch7.adb  | 56 +++++++++++++++++++++++++++++++++++++-------
 gcc/ada/exp_ch7.ads  |  7 ++++--
 3 files changed, 57 insertions(+), 15 deletions(-)
  

Patch

diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index a51e02bc308..428115f81ba 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -7345,12 +7345,13 @@  package body Exp_Aggr is
 
          --  If a transient scope has been created around the declaration, we
          --  need to attach the code to it so that the finalization actions of
-         --  the declaration will be inserted after it. Otherwise, we directly
-         --  insert it after the declaration and it will be analyzed only once
-         --  the declaration is processed.
+         --  the declaration will be inserted after it; otherwise, we directly
+         --  insert it after the declaration. In both cases, the code will be
+         --  analyzed after the declaration is processed, i.e. once the actual
+         --  subtype of the object is established.
 
          if Scope_Is_Transient and then Par = Node_To_Be_Wrapped then
-            Insert_Actions_After (Par, Aggr_Code);
+            Store_After_Actions_In_Scope_Without_Analysis (Aggr_Code);
          else
             Insert_List_After (Par, Aggr_Code);
          end if;
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index 171ad4ef395..a841d3af60f 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -514,7 +514,13 @@  package body Exp_Ch7 is
    --  cleanup actions are performed at the end of the block.
 
    procedure Store_Actions_In_Scope (AK : Scope_Action_Kind; L : List_Id);
-   --  Shared processing for Store_xxx_Actions_In_Scope
+   --  Shared processing for the Store_xxx_Actions_In_Scope routines: attach
+   --  the list L of actions to the list of actions stored in the top of the
+   --  scope stack specified by AK.
+
+   procedure Store_New_Actions_In_Scope (AK : Scope_Action_Kind; L : List_Id);
+   --  Same as above for the case where the list of actions stored in the top
+   --  of the scope stack specified by AK is empty.
 
    -------------------------------------------
    -- Unnesting procedures for CCG and LLVM --
@@ -8907,14 +8913,7 @@  package body Exp_Ch7 is
 
    begin
       if Is_Empty_List (Actions) then
-         Actions := L;
-
-         if Is_List_Member (SE.Node_To_Be_Wrapped) then
-            Set_Parent (L, Parent (SE.Node_To_Be_Wrapped));
-         else
-            Set_Parent (L, SE.Node_To_Be_Wrapped);
-         end if;
-
+         Store_New_Actions_In_Scope (AK, L);
          Analyze_List (L);
 
       elsif AK = Before then
@@ -8934,6 +8933,22 @@  package body Exp_Ch7 is
       Store_Actions_In_Scope (After, L);
    end Store_After_Actions_In_Scope;
 
+   ---------------------------------------------------
+   -- Store_After_Actions_In_Scope_Without_Analysis --
+   ---------------------------------------------------
+
+   procedure Store_After_Actions_In_Scope_Without_Analysis (L : List_Id) is
+      SE      : Scope_Stack_Entry renames Scope_Stack.Table (Scope_Stack.Last);
+      Actions : List_Id renames SE.Actions_To_Be_Wrapped (After);
+
+   begin
+      if Is_Empty_List (Actions) then
+         Store_New_Actions_In_Scope (After, L);
+      else
+         Insert_List_Before (First (Actions), L);
+      end if;
+   end Store_After_Actions_In_Scope_Without_Analysis;
+
    -----------------------------------
    -- Store_Before_Actions_In_Scope --
    -----------------------------------
@@ -8952,6 +8967,29 @@  package body Exp_Ch7 is
       Store_Actions_In_Scope (Cleanup, L);
    end Store_Cleanup_Actions_In_Scope;
 
+   --------------------------------
+   -- Store_New_Actions_In_Scope --
+   --------------------------------
+
+   procedure Store_New_Actions_In_Scope (AK : Scope_Action_Kind; L : List_Id)
+   is
+      SE      : Scope_Stack_Entry renames Scope_Stack.Table (Scope_Stack.Last);
+      Actions : List_Id renames SE.Actions_To_Be_Wrapped (AK);
+
+   begin
+      pragma Assert (Is_Empty_List (Actions));
+
+      Actions := L;
+
+      --  Set the Parent link to provide the context for the actions
+
+      if Is_List_Member (SE.Node_To_Be_Wrapped) then
+         Set_Parent (L, Parent (SE.Node_To_Be_Wrapped));
+      else
+         Set_Parent (L, SE.Node_To_Be_Wrapped);
+      end if;
+   end Store_New_Actions_In_Scope;
+
    ------------------
    -- Unnest_Block --
    ------------------
diff --git a/gcc/ada/exp_ch7.ads b/gcc/ada/exp_ch7.ads
index 22303d4c22f..d013eff9a45 100644
--- a/gcc/ada/exp_ch7.ads
+++ b/gcc/ada/exp_ch7.ads
@@ -311,7 +311,7 @@  package Exp_Ch7 is
    --  Return the node to be wrapped if the current scope is transient
 
    procedure Store_Before_Actions_In_Scope (L : List_Id);
-   --  Append the list L of actions to the end of the before-actions store in
+   --  Append the list L of actions to the end of the before-actions stored in
    --  the top of the scope stack (also analyzes these actions).
 
    procedure Store_After_Actions_In_Scope (L : List_Id);
@@ -324,9 +324,12 @@  package Exp_Ch7 is
    --  last call executed first). Within the list L for a single call, the
    --  actions are executed in the order in which they appear in this list.
 
+   procedure Store_After_Actions_In_Scope_Without_Analysis (L : List_Id);
+   --  Same as above, but without analyzing the actions
+
    procedure Store_Cleanup_Actions_In_Scope (L : List_Id);
    --  Prepend the list L of actions to the beginning of the cleanup-actions
-   --  store in the top of the scope stack.
+   --  stored in the top of the scope stack.
 
    procedure Wrap_Transient_Declaration (N : Node_Id);
    --  N is an object declaration. Expand the finalization calls after the