Patchwork [Ada] Minor tweak to expanded code for transient objects

login
register
mail settings
Submitter Arnaud Charlet
Date July 17, 2012, 10:15 a.m.
Message ID <20120717101500.GA25937@adacore.com>
Download mbox | patch
Permalink /patch/171387/
State New
Headers show

Comments

Arnaud Charlet - July 17, 2012, 10:15 a.m.
This change makes it so that the finalization blocks generated for controlled
transient objects, as well the final raise statement, are all wrapped into a
block, so as to make it easier for the back-end to understand the construct.

No functional changes.

Tested on x86_64-pc-linux-gnu, committed on trunk

2012-07-17  Eric Botcazou  <ebotcazou@adacore.com>

	* exp_ch7.adb (Process_Transient_Objects): Put all the
	finalization blocks and the final raise statement into a wrapper
	block.

Patch

Index: exp_ch7.adb
===================================================================
--- exp_ch7.adb	(revision 189565)
+++ exp_ch7.adb	(working copy)
@@ -4390,6 +4390,7 @@ 
          Obj_Id    : Entity_Id;
          Obj_Ref   : Node_Id;
          Obj_Typ   : Entity_Id;
+         Prev_Fin  : Node_Id := Empty;
          Stmt      : Node_Id;
          Stmts     : List_Id;
          Temp_Id   : Entity_Id;
@@ -4428,7 +4429,6 @@ 
                   Fin_Decls := New_List;
 
                   Build_Object_Declarations (Fin_Data, Fin_Decls, Loc);
-                  Insert_List_Before_And_Analyze (First_Object, Fin_Decls);
 
                   Built := True;
                end if;
@@ -4560,15 +4560,25 @@ 
                        Exception_Handlers => New_List (
                          Build_Exception_Handler (Fin_Data))));
 
-               Insert_After_And_Analyze (Last_Object, Fin_Block);
+               --  The single raise statement must be inserted after all the
+               --  finalization blocks. And we put everything into a wrapper
+               --  block to clearly expose the construct to the back-end.
 
-               --  The raise statement must be inserted after all the
-               --  finalization blocks.
+               if Present (Prev_Fin) then
+                  Insert_Before_And_Analyze (Prev_Fin, Fin_Block);
+               else
+                  Insert_After_And_Analyze (Last_Object,
+                    Make_Block_Statement (Loc,
+                      Declarations => Fin_Decls,
+                      Handled_Statement_Sequence =>
+                        Make_Handled_Sequence_Of_Statements (Loc,
+                          Statements => New_List (Fin_Block))));
 
-               if No (Last_Fin) then
                   Last_Fin := Fin_Block;
                end if;
 
+               Prev_Fin := Fin_Block;
+
             --  When the associated node is an array object, the expander may
             --  sometimes generate a loop and create transient objects inside
             --  the loop.