From patchwork Wed Feb 6 10:15:37 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnaud Charlet X-Patchwork-Id: 218529 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 0F1C52C029C for ; Wed, 6 Feb 2013 21:16:53 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1360750614; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Date:From:To:Cc:Subject:Message-ID: MIME-Version:Content-Type:Content-Disposition:User-Agent: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=mC6L23eO1SNNV+OmS5o9 V5WTKzM=; b=FcO8XCzZLHS5L/aNH/0d0UW914rAmU9DOD/PYhbtOOb3xOzjqXV6 0MIAFf3rDbpKK074tf9mBC8daF0Q0vrJOTlTaMuhLdIXAdAjYai3oghdp/EU4Ol2 97uVgGEr18Kg6NbNFo+voAJCoWtGnv2bI2YwaV+kyz48a09E30om5qk= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Received:Date:From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type:Content-Disposition:User-Agent:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=WZoDmM1uWNuxe47dDXoZQeJDhfhWlp/UbAVi6H6r7mThLcpzXOEkbZL64IXTLG 9Xu8iaiiGBgjGts9w21VGHXwpMIhDQreNFQHeruaD+moqE+VQK8IIhPB16Xs4pai bntS9otQCtoFM8m6BvMZcrPC42qKcygmZ2b43mVOD7its=; Received: (qmail 22620 invoked by alias); 6 Feb 2013 10:15:49 -0000 Received: (qmail 22558 invoked by uid 22791); 6 Feb 2013 10:15:47 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, RCVD_IN_HOSTKARMA_NO X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 06 Feb 2013 10:15:38 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id AB5A32E5BF; Wed, 6 Feb 2013 05:15:37 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id TMpTeyWBF9Cv; Wed, 6 Feb 2013 05:15:37 -0500 (EST) Received: from kwai.gnat.com (kwai.gnat.com [205.232.38.4]) by rock.gnat.com (Postfix) with ESMTP id 8CC612E1C3; Wed, 6 Feb 2013 05:15:37 -0500 (EST) Received: by kwai.gnat.com (Postfix, from userid 4192) id 8C4FE3FF09; Wed, 6 Feb 2013 05:15:37 -0500 (EST) Date: Wed, 6 Feb 2013 05:15:37 -0500 From: Arnaud Charlet To: gcc-patches@gcc.gnu.org Cc: Hristian Kirtchev Subject: [Ada] Finalization of temporary controlled function results Message-ID: <20130206101537.GA5784@adacore.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Finalization of temporary controlled function results in expression with actions nodes in the context of return statements: This patch adds logic to recognize a simple return statement as one of the cases that require special processing with respect to temporary controlled function results that appear in expression_with_actions nodes. ------------ -- Source -- ------------ -- types.ads with Ada.Finalization; use Ada.Finalization; package Types is type Ctrl is new Controlled with record Data : Natural := 1234; end record; function Equal_To_1 (Obj : Ctrl) return Boolean; 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 function Equal_To_1 (Obj : Ctrl) return Boolean is begin return Obj.Data = 1; end Equal_To_1; 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 function Must_Be_True return Boolean is function Factorial (Val : Natural) return Natural is begin if Val > 1 then return Val * Factorial (Val - 1); else return 1; end if; end Factorial; begin return Factorial (3) = 6 and then Equal_To_1 (Make_Ctrl (1)); end Must_Be_True; begin if not Must_Be_True then Put_Line ("ERROR: temporary function result finalized too early"); end if; end Main; ---------------------------- -- Compilation and output -- ---------------------------- $ gnatmake -q main.adb $ ./main fin fin Tested on x86_64-pc-linux-gnu, committed on trunk 2013-02-06 Hristian Kirtchev * exp_ch4.adb (Find_Enclosing_Context): Recognize a simple return statement as one of the cases that require special processing with respect to temporary controlled function results. (Process_Transient_Object): Do attempt to finalize a temporary controlled function result when the associated context is a simple return statement. Instead, leave this task to the general finalization mechanism. Index: exp_ch4.adb =================================================================== --- exp_ch4.adb (revision 195790) +++ exp_ch4.adb (working copy) @@ -5038,7 +5038,7 @@ -- Start of processing for Find_Enclosing_Context begin - -- The expression_with_action is in a case or if expression and + -- The expression_with_actions is in a case/if expression and -- the lifetime of any temporary controlled object is therefore -- extended. Find a suitable insertion node by locating the top -- most case or if expressions. @@ -5088,12 +5088,12 @@ return Par; - -- Shor circuit operators in complex expressions are converted + -- Short circuit operators in complex expressions are converted -- into expression_with_actions. else -- Take care of the case where the expression_with_actions - -- is burried deep inside an if statement. The temporary + -- is buried deep inside an IF statement. The temporary -- function result must be finalized before the then, elsif -- or else statements are evaluated. @@ -5123,7 +5123,7 @@ Top := Par; - -- The expression_with_action might be located in a pragm + -- The expression_with_actions might be located in a pragma -- in which case locate the pragma itself: -- pragma Precondition (... and then Ctrl_Func_Call ...); @@ -5133,10 +5133,16 @@ -- Obj [: Some_Typ] := ... and then Ctrl_Func_Call ...; + -- Another case to consider is an expression_with_actions as + -- part of a return statement: + + -- return ... and then Ctrl_Func_Call ...; + while Present (Par) loop if Nkind_In (Par, N_Assignment_Statement, N_Object_Declaration, - N_Pragma) + N_Pragma, + N_Simple_Return_Statement) then return Par; @@ -5238,23 +5244,32 @@ -- Temp := null; -- end if; - Insert_Action_After (Context, - Make_If_Statement (Loc, - Condition => - Make_Op_Ne (Loc, - Left_Opnd => New_Reference_To (Temp_Id, Loc), - Right_Opnd => Make_Null (Loc)), + -- When the expression_with_actions is part of a return statement, + -- there is no need to insert a finalization call, as the general + -- finalization mechanism (see Build_Finalizer) would take care of + -- the temporary function result on subprogram exit. Note that it + -- would also be impossible to insert the finalization code after + -- the return statement as this would make it unreachable. - Then_Statements => New_List ( - Make_Final_Call - (Obj_Ref => - Make_Explicit_Dereference (Loc, - Prefix => New_Reference_To (Temp_Id, Loc)), - Typ => Desig_Typ), + if Nkind (Context) /= N_Simple_Return_Statement then + Insert_Action_After (Context, + Make_If_Statement (Loc, + Condition => + Make_Op_Ne (Loc, + Left_Opnd => New_Reference_To (Temp_Id, Loc), + Right_Opnd => Make_Null (Loc)), - Make_Assignment_Statement (Loc, - Name => New_Reference_To (Temp_Id, Loc), - Expression => Make_Null (Loc))))); + Then_Statements => New_List ( + Make_Final_Call + (Obj_Ref => + Make_Explicit_Dereference (Loc, + Prefix => New_Reference_To (Temp_Id, Loc)), + Typ => Desig_Typ), + + Make_Assignment_Statement (Loc, + Name => New_Reference_To (Temp_Id, Loc), + Expression => Make_Null (Loc))))); + end if; end Process_Transient_Object; -- Start of processing for Process_Action