aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEd Schonberg <schonberg@adacore.com>2007-12-19 17:22:56 +0100
committerArnaud Charlet <charlet@gcc.gnu.org>2007-12-19 17:22:56 +0100
commit4a76b687c424b460021ad90e7ade96e66e4c0bf1 (patch)
tree526cb12d8201c69d84d1bff38327a77031be30a5 /gcc
parent10303118b35501a5e2f26fdaf91a3732e10cd9d7 (diff)
downloadgcc-4a76b687c424b460021ad90e7ade96e66e4c0bf1.zip
gcc-4a76b687c424b460021ad90e7ade96e66e4c0bf1.tar.gz
gcc-4a76b687c424b460021ad90e7ade96e66e4c0bf1.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/exp_aggr.adb84
1 files changed, 62 insertions, 22 deletions
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 2dd0f0c..f1e7fb4 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -1973,9 +1973,10 @@ package body Exp_Aggr is
Attach : Node_Id;
Init_Pr : Boolean) return List_Id
is
- L : constant List_Id := New_List;
- Ref : Node_Id;
- RC : RE_Id;
+ L : constant List_Id := New_List;
+ Ref : Node_Id;
+ RC : RE_Id;
+ Target_Type : Entity_Id;
begin
-- Generate:
@@ -1989,27 +1990,47 @@ package body Exp_Aggr is
Selector_Name => Make_Identifier (Loc, Name_uController));
Set_Assignment_OK (Ref);
- -- Ada 2005 (AI-287): Give support to default initialization of
- -- limited types and components.
+ -- Ada 2005 (AI-287): Give support to aggregates of limited
+ -- 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
- and then Present (Etype (Target))
- and then Is_Limited_Type (Etype (Target)))
- or else
- (Nkind (Target) = N_Selected_Component
- and then Present (Etype (Selector_Name (Target)))
- and then Is_Limited_Type (Etype (Selector_Name (Target))))
- or else
- (Nkind (Target) = N_Unchecked_Type_Conversion
- and then Present (Etype (Target))
- and then Is_Limited_Type (Etype (Target)))
- or else
- (Nkind (Target) = N_Unchecked_Expression
- and then Nkind (Expression (Target)) = N_Indexed_Component
- and then Present (Etype (Prefix (Expression (Target))))
- and then Is_Limited_Type (Etype (Prefix (Expression (Target)))))
+ if Nkind (Target) = N_Identifier then
+ Target_Type := Etype (Target);
+
+ elsif Nkind (Target) = N_Selected_Component then
+ Target_Type := Etype (Selector_Name (Target));
+
+ elsif Nkind (Target) = N_Unchecked_Type_Conversion then
+ Target_Type := Etype (Target);
+
+ elsif Nkind (Target) = N_Unchecked_Expression
+ and then Nkind (Expression (Target)) = N_Indexed_Component
+ then
+ Target_Type := Etype (Prefix (Expression (Target)));
+
+ else
+ 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
RC := RE_Limited_Record_Controller;
+
+ elsif Is_Inherently_Limited_Type (Target_Type) then
+ RC := RE_Limited_Record_Controller;
+
else
RC := RE_Record_Controller;
end if;
@@ -5183,6 +5204,19 @@ package body Exp_Aggr is
-- of assignment statements. Cases checked for are a nested aggregate
-- needing Late_Expansion, the presence of a tagged component which may
-- 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 --
@@ -5241,6 +5275,12 @@ package body Exp_Aggr is
or else not Compile_Time_Known_Aggregate (Expr_Q)
then
Static_Components := False;
+
+ if Is_Private_Type (Etype (Expr_Q))
+ and then Has_Discriminants (Etype (Expr_Q))
+ then
+ return True;
+ end if;
end if;
Next (C);
@@ -5333,7 +5373,7 @@ package body Exp_Aggr is
Convert_To_Assignments (N, Typ);
-- 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
-- size of the data.