aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2014-02-06 15:16:52 +0100
committerArnaud Charlet <charlet@gcc.gnu.org>2014-02-06 15:16:52 +0100
commitf29afe5f1445ba6c33116ca26eb8cd9a29a4a46a (patch)
tree5a8e13696c158c85c370de398856874654015769 /gcc
parentaa9b151a9e3630f78c1517d016fa26dc3277b506 (diff)
downloadgcc-f29afe5f1445ba6c33116ca26eb8cd9a29a4a46a.zip
gcc-f29afe5f1445ba6c33116ca26eb8cd9a29a4a46a.tar.gz
gcc-f29afe5f1445ba6c33116ca26eb8cd9a29a4a46a.tar.bz2
Code clean ups.
From-SVN: r207560
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/exp_aggr.adb52
1 files changed, 39 insertions, 13 deletions
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 5c0f4de..29366d0 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -3280,6 +3280,7 @@ package body Exp_Aggr is
T : Entity_Id;
Temp : Entity_Id;
+ Aggr_Code : List_Id;
Instr : Node_Id;
Target_Expr : Node_Id;
Parent_Kind : Node_Kind;
@@ -3361,9 +3362,7 @@ package body Exp_Aggr is
end if;
if Requires_Transient_Scope (Typ) then
- Establish_Transient_Scope
- (N, Sec_Stack =>
- Is_Controlled (Typ) or else Has_Controlled_Component (Typ));
+ Establish_Transient_Scope (N, Sec_Stack => Needs_Finalization (Typ));
end if;
-- If the aggregate is non-limited, create a temporary. If it is limited
@@ -3401,8 +3400,20 @@ package body Exp_Aggr is
Set_No_Initialization (Instr);
Insert_Action (N, Instr);
Initialize_Discriminants (Instr, T);
+
Target_Expr := New_Occurrence_Of (Temp, Loc);
- Insert_Actions (N, Build_Record_Aggr_Code (N, T, Target_Expr));
+ Aggr_Code := Build_Record_Aggr_Code (N, T, Target_Expr);
+
+ -- Save the last assignment statement associated with the aggregate
+ -- when building a controlled object. This reference is utilized by
+ -- the finalization machinery when marking an object as successfully
+ -- initialized.
+
+ if Needs_Finalization (T) then
+ Set_Last_Aggregate_Assignment (Temp, Last (Aggr_Code));
+ end if;
+
+ Insert_Actions (N, Aggr_Code);
Rewrite (N, New_Occurrence_Of (Temp, Loc));
Analyze_And_Resolve (N, T);
end if;
@@ -5702,17 +5713,15 @@ package body Exp_Aggr is
then
Convert_To_Assignments (N, Typ);
- -- Temporaries for controlled aggregates need to be attached to a final
- -- chain in order to be properly finalized, so it has to be created in
- -- the front-end
+ -- An aggregate used to initialize a controlled object must be turned
+ -- into component assignments as the components themselves may require
+ -- finalization actions such as adjustment.
- elsif Is_Controlled (Typ)
- or else Has_Controlled_Component (Base_Type (Typ))
- then
+ elsif Needs_Finalization (Typ) then
Convert_To_Assignments (N, Typ);
- -- Ada 2005 (AI-287): In case of default initialized components we
- -- convert the aggregate into assignments.
+ -- Ada 2005 (AI-287): In case of default initialized components we
+ -- convert the aggregate into assignments.
elsif Has_Default_Init_Comps (N) then
Convert_To_Assignments (N, Typ);
@@ -6188,9 +6197,26 @@ package body Exp_Aggr is
Typ : Entity_Id;
Target : Node_Id) return List_Id
is
+ Aggr_Code : List_Id;
+
begin
if Is_Record_Type (Etype (N)) then
- return Build_Record_Aggr_Code (N, Typ, Target);
+ Aggr_Code := Build_Record_Aggr_Code (N, Typ, Target);
+
+ -- Save the last assignment statement associated with the aggregate
+ -- when building a controlled object. This reference is utilized by
+ -- the finalization machinery when marking an object as successfully
+ -- initialized.
+
+ if Needs_Finalization (Typ)
+ and then Is_Entity_Name (Target)
+ and then Present (Entity (Target))
+ and then Ekind (Entity (Target)) = E_Variable
+ then
+ Set_Last_Aggregate_Assignment (Entity (Target), Last (Aggr_Code));
+ end if;
+
+ return Aggr_Code;
else pragma Assert (Is_Array_Type (Etype (N)));
return