https://gcc.gnu.org/g:62769289be76f5a413f24f8a0a0a08017d1efc63
commit r17-4765-g62769289be76f5a413f24f8a0a0a08017d1efc63 Author: Eric Botcazou <[email protected]> Date: Tue Sep 29 12:10:44 2026 +0200 Ada: Get rid of temporary in assignment of others-equivalent array aggregate The temporary is created to support potential sliding but it is not for an others aggregate, although the constructs are semantically equivalent. gcc/ada/ * exp_aggr.adb (Expand_Array_Aggregate): Turn an others-equivalent aggregate present in an assignment into an others aggregate. Diff: --- gcc/ada/exp_aggr.adb | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb index 56f43f8fd252..453727b63f49 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
