This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]