This patch corrects the transient object machinery to treat the renamed result of a controlled function call as a finalizable transient when the context is an expression with actions. If this was a different context, the lifetime of the result would be considered extended and not finalized.
------------ -- Source -- ------------ -- types.ads with Ada.Finalization; use Ada.Finalization; package Types is type Ctrl is new Limited_Controlled with record Val : Integer := 0; end record; function F1 (Obj : Ctrl) return Integer; function F2 (Val : Integer) return Ctrl'Class; procedure Finalize (Obj : in out Ctrl); procedure Test (Flag : Boolean; Obj : Ctrl); end Types; -- types.adb with Ada.Text_IO; use Ada.Text_IO; package body Types is procedure Finalize (Obj : in out Ctrl) is begin Put_Line ("fin" & Obj.Val'Img); end Finalize; function F1 (Obj : Ctrl) return Integer is begin return Obj.Val + 1; end F1; function F2 (Val : Integer) return Ctrl'Class is begin Put_Line ("ini" & Val'Img); return Ctrl'(Limited_Controlled with Val => Val); end F2; procedure Test (Flag : Boolean; Obj : Ctrl) is begin if Flag and then F2 (F1 (Obj)).Val = 42 then raise Program_Error; end if; end Test; end Types; -- main.adb with Ada.Text_IO; use Ada.Text_IO; with Types; use Types; procedure Main is begin declare Obj : Ctrl; begin Obj.Val := 1; Test (True, Obj); exception when others => Put_Line ("ERROR: unexpected exception 1"); end; declare Obj : Ctrl; begin Obj.Val := 41; Test (True, Obj); Put_Line ("ERROR: exception not raised"); exception when Program_Error => null; when others => Put_Line ("ERROR: unexpected exception 2"); end; end Main; ---------------------------- -- Compilation and output -- ---------------------------- $ gnatmake -q main.adb $ ./main ini 2 fin 2 fin 1 ini 42 fin 42 fin 41 Tested on x86_64-pc-linux-gnu, committed on trunk 2014-07-17 Hristian Kirtchev <kirtc...@adacore.com> * exp_util.adb (Is_Aliased): Transient objects within an expression with actions cannot be considered aliased.
Index: exp_util.adb =================================================================== --- exp_util.adb (revision 212719) +++ exp_util.adb (working copy) @@ -4557,6 +4557,15 @@ -- Start of processing for Is_Aliased begin + -- Aliasing in expression with actions does not matter because the + -- scope of the transient object is always limited by the scope of + -- the EWA. Such objects are always hooked and always finalized at + -- the end of the EWA's scope. + + if Nkind (Rel_Node) = N_Expression_With_Actions then + return False; + end if; + Stmt := First_Stmt; while Present (Stmt) loop if Nkind (Stmt) = N_Object_Declaration then @@ -7343,7 +7352,7 @@ elsif Is_Access_Type (Obj_Typ) and then Present (Status_Flag_Or_Transient_Decl (Obj_Id)) and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) = - N_Object_Declaration + N_Object_Declaration and then Is_Finalizable_Transient (Status_Flag_Or_Transient_Decl (Obj_Id), Decl) then