The temporary is created to support potential sliding but it is not for an
others aggregate, although the constructs are semantically equivalent.

Tested on x86-64/Linux, applied on the mainline.


2026-09-29  Eric Botcazou  <[email protected]>
    
        * exp_aggr.adb (Expand_Array_Aggregate): Turn an others-equivalent
        aggregate present in an assignment into an others aggregate.

-- 
Eric Botcazou
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 56f43f8fd25..453727b63f4 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -6313,6 +6313,56 @@ package body Exp_Aggr is
          return;
       end if;
 
+      --  Minor optimization: make sure that the 3 equivalent constructs
+
+      --    S := (others => C);
+      --    S := (S'Range => C);
+      --    S := (S'First .. S'Last => C);
+
+      --  where S denotes an entity, are handled the same way downstream, in
+      --  particular with regard to sliding, by turning the last 2 constructs
+      --  into the first (the second has already been turned into the third).
+
+      if Nkind (Parent (N)) = N_Assignment_Statement
+        and then Is_Entity_Name (Name (Parent (N)))
+        and then Aggr_Dimension = 1
+        and then Is_Single_Aggregate (N)
+        and then
+          Nkind (First (Component_Associations (N))) = N_Component_Association
+        and then
+          Nkind (First (Choice_List (First (Component_Associations (N))))) =
+                                                                        N_Range
+      then
+         declare
+            Assoc  : constant Node_Id := First (Component_Associations (N));
+            Bounds : constant Range_Nodes :=
+              Get_Index_Bounds (First (Choice_List (Assoc)));
+
+         begin
+            if Nkind (Bounds.First) = N_Attribute_Reference
+              and then Attribute_Name (Bounds.First) = Name_First
+              and then Is_Entity_Name (Prefix (Bounds.First))
+              and then
+                Entity (Prefix (Bounds.First)) = Entity (Name (Parent (N)))
+              and then Nkind (Bounds.Last) = N_Attribute_Reference
+              and then Attribute_Name (Bounds.Last) = Name_Last
+              and then Is_Entity_Name (Prefix (Bounds.Last))
+              and then
+                Entity (Prefix (Bounds.Last)) = Entity (Name (Parent (N)))
+            then
+               Rewrite (N, Make_Aggregate (Sloc (N),
+                 Component_Associations => New_List (
+                   Make_Component_Association (Sloc (Assoc),
+                     Choices     =>
+                       New_List (Make_Others_Choice (Sloc (Assoc))),
+                     Expression  => Relocate_Node (Expression (Assoc)),
+                     Box_Present => Box_Present (Assoc)))));
+               Analyze_And_Resolve (N, Typ);
+               return;
+            end if;
+         end;
+      end if;
+
       --  Otherwise, if a transient scope is required, create it now
 
       if Requires_Transient_Scope (Typ) then

Reply via email to