From: Eric Botcazou <[email protected]>
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