The compiler crashes on the recursive call to a function with an In-Out or Out 
parameter passed by copy, in Ada 2012 mode.

Tested on i586-suse-linux, applied on mainline and 4.7 branch.


2012-07-03  Eric Botcazou  <ebotca...@adacore.com>

        * gcc-interface/trans.c (Call_to_gnu): Robustify test for function case
        if the CICO mechanism is used.


2012-07-03  Eric Botcazou  <ebotca...@adacore.com>

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


-- 
Eric Botcazou
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 249771)
+++ gcc-interface/trans.c	(revision 249772)
@@ -4085,7 +4085,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gn
 
       /* The first entry is for the actual return value if this is a
 	 function, so skip it.  */
-      if (TREE_VALUE (gnu_cico_list) == void_type_node)
+      if (function_call)
 	gnu_cico_list = TREE_CHAIN (gnu_cico_list);
 
       if (Nkind (Name (gnat_node)) == N_Explicit_Dereference)
@@ -4189,8 +4189,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gn
 	 return value from it and update the return type.  */
       if (TYPE_CI_CO_LIST (gnu_subprog_type))
 	{
-	  tree gnu_elmt = value_member (void_type_node,
-					TYPE_CI_CO_LIST (gnu_subprog_type));
+	  tree gnu_elmt = TYPE_CI_CO_LIST (gnu_subprog_type);
 	  gnu_call = build_component_ref (gnu_call, NULL_TREE,
 					  TREE_PURPOSE (gnu_elmt), false);
 	  gnu_result_type = TREE_TYPE (gnu_call);
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 189199)
+++ gcc-interface/trans.c	(working copy)
@@ -4084,7 +4084,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gn
 
       /* The first entry is for the actual return value if this is a
 	 function, so skip it.  */
-      if (TREE_VALUE (gnu_cico_list) == void_type_node)
+      if (function_call)
 	gnu_cico_list = TREE_CHAIN (gnu_cico_list);
 
       if (Nkind (Name (gnat_node)) == N_Explicit_Dereference)
@@ -4188,8 +4188,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gn
 	 return value from it and update the return type.  */
       if (TYPE_CI_CO_LIST (gnu_subprog_type))
 	{
-	  tree gnu_elmt = value_member (void_type_node,
-					TYPE_CI_CO_LIST (gnu_subprog_type));
+	  tree gnu_elmt = TYPE_CI_CO_LIST (gnu_subprog_type);
 	  gnu_call = build_component_ref (gnu_call, NULL_TREE,
 					  TREE_PURPOSE (gnu_elmt), false);
 	  gnu_result_type = TREE_TYPE (gnu_call);
-- { dg-do compile }
-- { dg-options "-gnat2012" }

function Recursive_Call (File : String; Status : out Boolean) return Boolean is
begin
  if File /= "/dev/null" then
    return Recursive_Call ("/dev/null", Status);
  end if;
  return False;
end;

Reply via email to