Commit 4a76b687 by Ed Schonberg Committed by Arnaud Charlet

exp_aggr.adb (Not_OK_For_Backend): A component of a private type with…

exp_aggr.adb (Not_OK_For_Backend): A component of a private type with discriminants forces expansion of the...

2007-12-19  Ed Schonberg  <schonberg@adacore.com>

	* exp_aggr.adb (Not_OK_For_Backend): A component of a private type with
	discriminants forces expansion of the aggregate into assignments.
	(Init_Record_Controller):  If the type of the aggregate is untagged and
	is not inherently limited, the record controller is not limited either.

From-SVN: r131071
parent 10303118
...@@ -1973,9 +1973,10 @@ package body Exp_Aggr is ...@@ -1973,9 +1973,10 @@ package body Exp_Aggr is
Attach : Node_Id; Attach : Node_Id;
Init_Pr : Boolean) return List_Id Init_Pr : Boolean) return List_Id
is is
L : constant List_Id := New_List; L : constant List_Id := New_List;
Ref : Node_Id; Ref : Node_Id;
RC : RE_Id; RC : RE_Id;
Target_Type : Entity_Id;
begin begin
-- Generate: -- Generate:
...@@ -1989,27 +1990,47 @@ package body Exp_Aggr is ...@@ -1989,27 +1990,47 @@ package body Exp_Aggr is
Selector_Name => Make_Identifier (Loc, Name_uController)); Selector_Name => Make_Identifier (Loc, Name_uController));
Set_Assignment_OK (Ref); Set_Assignment_OK (Ref);
-- Ada 2005 (AI-287): Give support to default initialization of -- Ada 2005 (AI-287): Give support to aggregates of limited
-- limited types and components. -- types. If the type is intrinsically_limited the controller
-- is limited as well. If it is tagged and limited then so is
-- the controller. Otherwise an untagged type may have limited
-- components without its full view being limited, so the
-- controller is not limited.
if (Nkind (Target) = N_Identifier if Nkind (Target) = N_Identifier then
and then Present (Etype (Target)) Target_Type := Etype (Target);
and then Is_Limited_Type (Etype (Target)))
or else elsif Nkind (Target) = N_Selected_Component then
(Nkind (Target) = N_Selected_Component Target_Type := Etype (Selector_Name (Target));
and then Present (Etype (Selector_Name (Target)))
and then Is_Limited_Type (Etype (Selector_Name (Target)))) elsif Nkind (Target) = N_Unchecked_Type_Conversion then
or else Target_Type := Etype (Target);
(Nkind (Target) = N_Unchecked_Type_Conversion
and then Present (Etype (Target)) elsif Nkind (Target) = N_Unchecked_Expression
and then Is_Limited_Type (Etype (Target))) and then Nkind (Expression (Target)) = N_Indexed_Component
or else then
(Nkind (Target) = N_Unchecked_Expression Target_Type := Etype (Prefix (Expression (Target)));
and then Nkind (Expression (Target)) = N_Indexed_Component
and then Present (Etype (Prefix (Expression (Target)))) else
and then Is_Limited_Type (Etype (Prefix (Expression (Target))))) Target_Type := Etype (Target);
end if;
-- If the target has not been analyzed yet, as will happen with
-- delayed expansion, use the given type (either the aggregate
-- type or an ancestor) to determine limitedness.
if No (Target_Type) then
Target_Type := Typ;
end if;
if (Is_Tagged_Type (Target_Type))
and then Is_Limited_Type (Target_Type)
then then
RC := RE_Limited_Record_Controller; RC := RE_Limited_Record_Controller;
elsif Is_Inherently_Limited_Type (Target_Type) then
RC := RE_Limited_Record_Controller;
else else
RC := RE_Record_Controller; RC := RE_Record_Controller;
end if; end if;
...@@ -5183,6 +5204,19 @@ package body Exp_Aggr is ...@@ -5183,6 +5204,19 @@ package body Exp_Aggr is
-- of assignment statements. Cases checked for are a nested aggregate -- of assignment statements. Cases checked for are a nested aggregate
-- needing Late_Expansion, the presence of a tagged component which may -- needing Late_Expansion, the presence of a tagged component which may
-- need tag adjustment, and a bit unaligned component reference. -- need tag adjustment, and a bit unaligned component reference.
--
-- We also force expansion into assignments if a component is of a
-- mutable type (including a private type with discriminants) because
-- in that case the size of the component to be copied may be smaller
-- than the side of the target, and there is no simple way for gigi
-- to compute the size of the object to be copied.
--
-- NOTE: This is part of the ongoing work to define precisely the
-- interface between front-end and back-end handling of aggregates.
-- In general it is desirable to pass aggregates as they are to gigi,
-- in order to minimize elaboration code. This is one case where the
-- semantics of Ada complicate the analysis and lead to anomalies in
-- the gcc back-end if the aggregate is not expanded into assignments.
---------------------------------- ----------------------------------
-- Component_Not_OK_For_Backend -- -- Component_Not_OK_For_Backend --
...@@ -5241,6 +5275,12 @@ package body Exp_Aggr is ...@@ -5241,6 +5275,12 @@ package body Exp_Aggr is
or else not Compile_Time_Known_Aggregate (Expr_Q) or else not Compile_Time_Known_Aggregate (Expr_Q)
then then
Static_Components := False; Static_Components := False;
if Is_Private_Type (Etype (Expr_Q))
and then Has_Discriminants (Etype (Expr_Q))
then
return True;
end if;
end if; end if;
Next (C); Next (C);
...@@ -5333,7 +5373,7 @@ package body Exp_Aggr is ...@@ -5333,7 +5373,7 @@ package body Exp_Aggr is
Convert_To_Assignments (N, Typ); Convert_To_Assignments (N, Typ);
-- If some components are mutable, the size of the aggregate component -- If some components are mutable, the size of the aggregate component
-- may be disctinct from the default size of the type component, so -- may be distinct from the default size of the type component, so
-- we need to expand to insure that the back-end copies the proper -- we need to expand to insure that the back-end copies the proper
-- size of the data. -- size of the data.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment