This fixes an oversight in the recent implementation of functions with In Out 
parameters for Ada 2012, which leads to wrong code if the function contains a 
nested subprogram which also takes an In Out parameter with elementary type.

Tested on x86_64-suse-linux, applied on all active branches.


2013-09-18  Eric Botcazou  <ebotca...@adacore.com>

        * gcc-interface/trans.c (Subprogram_Body_to_gnu): Pop the stack of
        return variables for subprograms using the CICO mechanism.


2013-09-18  Eric Botcazou  <ebotca...@adacore.com>

        * gnat.dg/in_out_parameter4.adb: New test.


-- 
Eric Botcazou
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 202681)
+++ gcc-interface/trans.c	(working copy)
@@ -3605,6 +3605,8 @@ Subprogram_Body_to_gnu (Node_Id gnat_nod
     {
       tree gnu_retval;
 
+      gnu_return_var_stack->pop ();
+
       add_stmt (gnu_result);
       add_stmt (build1 (LABEL_EXPR, void_type_node,
 			gnu_return_label_stack->last ()));
-- { dg-do run }
-- { dg-options "-gnat12 -gnatVa" }

procedure In_Out_Parameter4 is

   type Enum is (E_Undetermined, E_Down, E_Up);
   subtype Status_T is Enum range E_Down .. E_Up;

   function Recurse (Val : in out Integer) return Status_T is

     Result : Status_T;

     procedure Dummy (I : in out Integer) is begin null; end;

   begin
     if Val > 500 then
       Val := Val - 1;
       Result := Recurse (Val);
       return Result;
     else
       return E_UP;
     end if;
   end;

   Val : Integer := 501;
   S : Status_T;

begin
   S := Recurse (Val);
end;

Reply via email to