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 <ebotca...@adacore.com> * exp_ch7.adb (Process_Transient_Objects): Put all the finalization blocks and the final raise statement into a wrapper block.
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.