From: Eric Botcazou <ebotca...@adacore.com> 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. Tested on x86_64-pc-linux-gnu, committed on master. --- 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 846665eae20..86d886a302c 100644 --- a/gcc/ada/exp_aggr.adb +++ b/gcc/ada/exp_aggr.adb @@ -5946,12 +5946,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; @@ -8872,6 +8867,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 17fa38b7ca3..aa79616c609 100644 --- a/gcc/ada/exp_aggr.ads +++ b/gcc/ada/exp_aggr.ads @@ -58,6 +58,10 @@ package Exp_Aggr is -- Returns True if N is a conditional expression 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. + function Static_Array_Aggregate (N : Node_Id) return Boolean; -- N is an array aggregate that may have a component association with -- an others clause and a range. If bounds are static and the expressions diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb index ff808aadea8..139fce8b288 100644 --- a/gcc/ada/exp_ch3.adb +++ b/gcc/ada/exp_ch3.adb @@ -5429,17 +5429,22 @@ package body Exp_Ch3 is if not Is_Bit_Packed_Array (Typ) then 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; -- 2.43.0