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;