This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
This patch adds machinery to properly finalize temporary controlled function results that appear in N_Expression_With_Actions nodes as well as case and if expressions. In general, such temporaries must be finalized after the related context is elaborated/evaluated. ------------ -- Source -- ------------ -- types.ads with Ada.Finalization; use Ada.Finalization; package Types is type Ctrl is new Controlled with record Data : Natural := 1234; end record; procedure Finalize (Obj : in out Ctrl); function Make_Ctrl (Val : Natural) return 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 Obj.Data := 0; Put_Line (" fin"); end Finalize; function Make_Ctrl (Val : Natural) return Ctrl is begin return (Controlled with Val); end Make_Ctrl; end Types; -- main.adb with Ada.Text_IO; use Ada.Text_IO; with Types; use Types; procedure Main is procedure Ensure_Value (Val : Natural; Exp : Natural; Act : Natural) is begin if Val /= Exp then Put_Line ("ERROR: transient finalized too early"); Put_Line (" Expected:" & Exp'Img); Put_Line (" Got :" & Act'Img); end if; end Ensure_Value; function Factorial (Val : Natural) return Natural is begin if Val > 1 then return Factorial (Val - 1) * Val; else return 1; end if; end Factorial; Exp : constant Natural := 9876; Junk : constant Natural := 5432; Flag : Boolean; Val : Natural; begin Put_Line ("Case expression"); Val := (case Factorial (3) is when 6 => Make_Ctrl (Exp).Data, when others => Junk); Ensure_Value (Val, Exp, Junk); Put_Line ("If expression"); Val := (if Factorial (3) = 6 then Make_Ctrl (Exp).Data else Junk); Ensure_Value (Val, Exp, Junk); Put_Line ("If statement"); if Val = Exp and then Make_Ctrl (Exp).Data = Exp then Put_Line (" then statements"); end if; Put_Line ("Assignment"); Flag := Val = Exp and then Make_Ctrl (Exp).Data = Exp; Put_Line ("End"); end Main; ---------------------------- -- Compilation and output -- ---------------------------- $ gnatmake -q -gnat12 main.adb $ ./main Case expression fin fin If expression fin fin If statement fin fin then statements Assignment fin fin End Tested on x86_64-pc-linux-gnu, committed on trunk 2013-02-06 Hristian Kirtchev <kirtchev@adacore.com> * exp_ch4.adb (Expand_N_Expression_With_Actions): Rewritten. This routine should be able to properly detect controlled transient objects in its actions and generate the appropriate finalization actions. * exp_ch6.adb (Enclosing_Context): Removed. (Expand_Ctrl_Function_Call): Remove local subprogram and constant. Use routine Within_Case_Or_If_Expression to determine whether the lifetime of the function result must be extended to match that of the context. * exp_util.ads, exp_util.adb (Within_Case_Or_If_Expression): New routine.
Attachment:
difs
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |