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]

[Ada] Missing finalization of a transient class-wide function result


This patch corrects the transient object machinery to disregard aliasing when
the associated context is a Boolean expression with actions. This is because
the Boolean result is always known after the action list has been evaluated,
therefore the transient objects must be finalized at that point.

------------
-- 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-29  Hristian Kirtchev  <kirtchev@adacore.com>

	* exp_ch4.adb (Process_Transient_Object): Remove constant
	In_Cond_Expr, use its initialization expression in place.
	* exp_ch7.adb (Process_Declarations): There is no need to check
	that a transient object being hooked is controlled as it would
	not have been hooked in the first place.
	* exp_util.adb (Is_Aliased): 'Reference-d or renamed transient
	objects are not considered aliased when the related context is
	a Boolean expression_with_actions.
	(Requires_Cleanup_Actions): There is no need to check that a transient
	object being hooked is controlled as it would not have been hooked in
	the first place.

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]