Comments
Patch
===================================================================
@@ -1795,6 +1795,19 @@ package body Sem_Aggr is
Expander_Mode_Save_And_Set (False);
Full_Analysis := False;
Analyze (Expr);
+
+ -- If the expression is a literal, propagate this info
+ -- to the expression in the association, to enable some
+ -- optimizations downstream.
+
+ if Is_Entity_Name (Expr)
+ and then Present (Entity (Expr))
+ and then Ekind (Entity (Expr)) = E_Enumeration_Literal
+ then
+ Analyze_And_Resolve
+ (Expression (Assoc), Component_Typ);
+ end if;
+
Full_Analysis := Save_Analysis;
Expander_Mode_Restore;
===================================================================
@@ -3773,6 +3773,13 @@ package body Exp_Aggr is
then
null;
+ elsif Is_Entity_Name (Expression (Expr))
+ and then Present (Entity (Expression (Expr)))
+ and then Ekind (Entity (Expression (Expr))) =
+ E_Enumeration_Literal
+ then
+ null;
+
elsif Nkind (Expression (Expr)) /= N_Aggregate
or else not Compile_Time_Known_Aggregate (Expression (Expr))
or else Expansion_Delayed (Expression (Expr))
@@ -5491,6 +5498,14 @@ package body Exp_Aggr is
C := First (Comps);
while Present (C) loop
+
+ -- If the component has box initialization, expansion is needed
+ -- and component is not ready for backend.
+
+ if Box_Present (C) then
+ return True;
+ end if;
+
if Nkind (Expression (C)) = N_Qualified_Expression then
Expr_Q := Expression (Expression (C));
else
@@ -5576,13 +5591,32 @@ package body Exp_Aggr is
end if;
-- Ada 2005 (AI-318-2): We need to convert to assignments if components
- -- are build-in-place function calls. This test could be more specific,
- -- but doing it for all inherently limited aggregates seems harmless.
- -- The assignments will turn into build-in-place function calls (see
- -- Make_Build_In_Place_Call_In_Assignment).
+ -- are build-in-place function calls. The assignments will each turn
+ -- into a build-in-place function call. If components are all static,
+ -- we can pass the aggregate to the backend regardless of limitedness.
+
+ -- Extension aggregates, aggregates in extended return statements, and
+ -- aggregates for C++ imported types must be expanded.
if Ada_Version >= Ada_05 and then Is_Inherently_Limited_Type (Typ) then
- Convert_To_Assignments (N, Typ);
+ if Nkind (Parent (N)) /= N_Object_Declaration then
+ Convert_To_Assignments (N, Typ);
+
+ elsif Nkind (N) = N_Extension_Aggregate
+ or else Convention (Typ) = Convention_CPP
+ then
+ Convert_To_Assignments (N, Typ);
+
+ elsif not Size_Known_At_Compile_Time (Typ)
+ or else Component_Not_OK_For_Backend
+ or else not Static_Components
+ then
+ Convert_To_Assignments (N, Typ);
+
+ else
+ Set_Compile_Time_Known_Aggregate (N);
+ Set_Expansion_Delayed (N, False);
+ end if;
-- Gigi doesn't handle properly temporaries of variable size
-- so we generate it in the front-end
This patch optimizes the handling of aggregates with static components, and allows more complex nested aggregates to be handled by the backend without any elaboration code. This applies in particular to aggregates of a limited type, which previously were always expanded into assignments. The following must compile quietly: --- pragma Restrictions (No_Elaboration_Code); package Elab is pragma Preelaborate; procedure Test; function Probe (X : Integer) return Boolean; end Elab; --- pragma Restrictions (No_Elaboration_Code); with Fair_Locks; package body Elab is use Fair_Locks; Lock : Fair_Lock := (Spinning => (others => False)); Complex : Tagged_Lock := (Contents => (others => False)); procedure Test is begin if not Lock.Spinning (3) then Lock.Spinning (2) := True; end if; end Test; function Probe (X : Integer) return Boolean is begin return Lock.Spinning (X); end Probe; end Elab; --- package Fair_Locks is pragma Preelaborate; type Spinning_Array is array (1 .. 16) of Boolean; type Fair_Lock is limited record Spinning : Spinning_Array := (others => False); end record; type Tagged_Lock is tagged limited record Contents : Spinning_Array := (others => False); end record; end Fair_Locks; Tested on x86_64-pc-linux-gnu, committed on trunk 2010-10-08 Ed Schonberg <schonberg@adacore.com> * sem_aggr.adb (Resolve_Array_Aggregate): If the expression in an others choice is a literal analyze it now to enable later optimizations. * exp_aggr.adb (Expand_Record_Aggregate): An aggregate with static size and components can be handled by the backend even if it is of a limited type.