This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch, Fortran] PR 39577 - fix -fcheck=recursion
- From: Tobias Burnus <burnus at net-b dot de>
- To: fortran at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Fri, 3 Apr 2009 21:21:02 +0200
- Subject: [Patch, Fortran] PR 39577 - fix -fcheck=recursion
This fixes the -fcheck=recursion option. The current trunk
version only works for subroutine (without "return"). In
the other cases, the recursion-check variable was not
resetted. (Before one had something like
return _result;
recursioncheck = false;
which of cause does not work.)
The error message of entry is not ideal ("master.0.f" rather
than "procedure 'f'" or "entry 'g'") but I think it is
sufficient, especially since the line number is given.
Build and being regtested on x86-64-linux.
OK for the trunk?
Tobias
2009-04-03 Tobias Burnus <burnus@net-b.de>
PR fortran/39577
* trans-decl.c (gfc_generate_function_code): Move recursive
check to the right position.
2009-04-03 Tobias Burnus <burnus@net-b.de>
PR fortran/39577
* gfortran.dg/recursive_check_8.f90: New.
* gfortran.dg/recursive_check_9.f90: New.
* gfortran.dg/recursive_check_10.f90: New.
* gfortran.dg/recursive_check_11.f90: New.
* gfortran.dg/recursive_check_12.f90: New.
* gfortran.dg/recursive_check_13.f90: New.
Index: gcc/fortran/trans-decl.c
===================================================================
--- gcc/fortran/trans-decl.c (Revision 145514)
+++ gcc/fortran/trans-decl.c (Arbeitskopie)
@@ -3953,6 +3953,13 @@ gfc_generate_function_code (gfc_namespac
gfc_add_expr_to_block (&block, tmp);
+ /* Reset recursion-check variable. */
+ if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION) && !sym->attr.recursive)
+ {
+ gfc_add_modify (&block, recurcheckvar, boolean_false_node);
+ recurcheckvar = NULL;
+ }
+
if (result == NULL_TREE)
{
/* TODO: move to the appropriate place in resolve.c. */
@@ -3975,11 +3982,16 @@ gfc_generate_function_code (gfc_namespac
}
}
else
- gfc_add_expr_to_block (&block, tmp);
+ {
+ gfc_add_expr_to_block (&block, tmp);
+ /* Reset recursion-check variable. */
+ if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION) && !sym->attr.recursive)
+ {
+ gfc_add_modify (&block, recurcheckvar, boolean_false_node);
+ recurcheckvar = NULL;
+ }
+ }
- /* Reset recursion-check variable. */
- if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION) && !sym->attr.recursive)
- gfc_add_modify (&block, recurcheckvar, boolean_false_node);
/* Add all the decls we created during processing. */
decl = saved_function_decls;
Index: gcc/testsuite/gfortran.dg/recursive_check_10.f90
===================================================================
--- gcc/testsuite/gfortran.dg/recursive_check_10.f90 (Revision 0)
+++ gcc/testsuite/gfortran.dg/recursive_check_10.f90 (Revision 0)
@@ -0,0 +1,25 @@
+! { dg-do 'run' }
+! { dg-options "-fcheck=recursion" }
+!
+! PR fortran/39577
+!
+! OK - no recursion
+program test
+ integer :: i
+ i = f(.false.)
+ print *,i
+ i = f(.false.)
+ print *,i
+contains
+ integer function f(rec)
+ logical :: rec
+ if(rec) then
+ f = g()
+ else
+ f = 42
+ end if
+ end function f
+ integer function g()
+ g = f(.false.)
+ end function g
+end program test
Index: gcc/testsuite/gfortran.dg/recursive_check_11.f90
===================================================================
--- gcc/testsuite/gfortran.dg/recursive_check_11.f90 (Revision 0)
+++ gcc/testsuite/gfortran.dg/recursive_check_11.f90 (Revision 0)
@@ -0,0 +1,28 @@
+! { dg-do 'run' }
+! { dg-options "-fcheck=recursion" }
+! { dg-shouldfail "Recursion check" }
+!
+! { dg-output "Fortran runtime error: Recursive call to nonrecursive procedure 'f'" }
+!
+! PR fortran/39577
+!
+! wrong - recursion
+program test
+ integer :: i
+ i = f(.false.)
+ print *,i
+ i = f(.true.)
+ print *,i
+contains
+ integer function f(rec)
+ logical :: rec
+ if(rec) then
+ f = g()
+ else
+ f = 42
+ end if
+ end function f
+ integer function g()
+ g = f(.false.)
+ end function g
+end program test
Index: gcc/testsuite/gfortran.dg/recursive_check_12.f90
===================================================================
--- gcc/testsuite/gfortran.dg/recursive_check_12.f90 (Revision 0)
+++ gcc/testsuite/gfortran.dg/recursive_check_12.f90 (Revision 0)
@@ -0,0 +1,29 @@
+! { dg-do 'run' }
+! { dg-options "-fcheck=recursion" }
+!
+! PR fortran/39577
+!
+! OK - no recursion
+module m
+ implicit none
+contains
+ subroutine f(rec)
+ logical :: rec
+ if(rec) then
+ call h()
+ end if
+ return
+ entry g()
+ end subroutine f
+ subroutine h()
+ call f(.false.)
+ end subroutine h
+end module m
+
+program test
+ use m
+ implicit none
+ call f(.false.)
+ call f(.false.)
+end program test
+! { dg-final { cleanup-modules "m" } }
Index: gcc/testsuite/gfortran.dg/recursive_check_13.f90
===================================================================
--- gcc/testsuite/gfortran.dg/recursive_check_13.f90 (Revision 0)
+++ gcc/testsuite/gfortran.dg/recursive_check_13.f90 (Revision 0)
@@ -0,0 +1,32 @@
+! { dg-do 'run' }
+! { dg-options "-fcheck=recursion" }
+! { dg-shouldfail "Recursion check" }
+!
+! { dg-output "Fortran runtime error: Recursive call to nonrecursive procedure 'master.0.f'" }
+!
+! PR fortran/39577
+!
+! invalid - recursion
+module m
+ implicit none
+contains
+ subroutine f(rec)
+ logical :: rec
+ if(rec) then
+ call h()
+ end if
+ return
+ entry g()
+ end subroutine f
+ subroutine h()
+ call f(.false.)
+ end subroutine h
+end module m
+
+program test
+ use m
+ implicit none
+ call f(.false.)
+ call f(.true.)
+end program test
+! { dg-final { cleanup-modules "m" } }
Index: gcc/testsuite/gfortran.dg/recursive_check_8.f90
===================================================================
--- gcc/testsuite/gfortran.dg/recursive_check_8.f90 (Revision 0)
+++ gcc/testsuite/gfortran.dg/recursive_check_8.f90 (Revision 0)
@@ -0,0 +1,22 @@
+! { dg-do 'run' }
+! { dg-options "-fcheck=recursion" }
+!
+! PR fortran/39577
+!
+! OK - no recursion
+program test
+ call f(.false.)
+ call f(.false.)
+contains
+ subroutine f(rec)
+ logical :: rec
+ if(rec) then
+ call g()
+ end if
+ return
+ end subroutine f
+ subroutine g()
+ call f(.false.)
+ return
+ end subroutine g
+end program test
Index: gcc/testsuite/gfortran.dg/recursive_check_9.f90
===================================================================
--- gcc/testsuite/gfortran.dg/recursive_check_9.f90 (Revision 0)
+++ gcc/testsuite/gfortran.dg/recursive_check_9.f90 (Revision 0)
@@ -0,0 +1,25 @@
+! { dg-do 'run' }
+! { dg-options "-fcheck=recursion" }
+! { dg-shouldfail "Recursion check" }
+!
+! { dg-output "Fortran runtime error: Recursive call to nonrecursive procedure 'f'" }
+!
+! PR fortran/39577
+!
+! Invalid - recursion
+program test
+ call f(.false.)
+ call f(.true.)
+contains
+ subroutine f(rec)
+ logical :: rec
+ if(rec) then
+ call g()
+ end if
+ return
+ end subroutine f
+ subroutine g()
+ call f(.false.)
+ return
+ end subroutine g
+end program test