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 38507 -- goto to end do is legal.


The attached patch fixes the problem reported in PR fortran/38507.
This removes a portion of the patch committed by Tobi Schluter to
fix PR fortran/18937.  (Apologies to Tobi about lack of a umlaut.)

Consider

   program a
   integer i
   do i = 1, 3
      if (i == 2) goto 10
      print *, i
10 end do
   end 

Trunk and 4.3 report

REMOVE:kargl[204] gfortran43 -o z k4.f90
k4.f90:4.25:

      if (i == 2) goto 10
                        1
k4.f90:6.9:

10 end do
        2
Warning: Deleted feature: GOTO at (1) jumps to END of construct at (2)

This is incorrect.  Annex B states

   (2) Branching to an END IF statement from outside its block.
       In Fortran 77, and for consistency also in Fortran 90, it was
       possible to branch to an END IF statement from outside the IF
       construct; this has been deleted.  A similar result can be
       achieved by branching to a CONTINUE statement that is immediately
       after the END IF statement.

Note, END DO is not mentioned in the above or any other Delete Features
clause.  Additionally, the above program should have the semantics of
using CYCLE instead of the GOTO 10.  See PR fortran/17708 for the fix
that implemented this semantic.

In considering Annex B, it seems that gfortran has the logic backwards.
This patch does not fix this problem, but consider

program a
   integer i
   i = 1
   if (i == 1) then
     goto 10
     i = 2
10 end if 
   goto 20
   if (i == 2) then
      i = 3
20 end if
end program a

REMOVE:kargl[216] gfc4x -o z k5.f90
k5.f90:6.12:

     goto 10
           1
k5.f90:8.10:

10 end if 
         2
Warning: Deleted feature: GOTO at (1) jumps to END of construct at (2)

This is wrong.  The GOTO 10 jumps to the ENDIF of the block that
contains the GOTO.  This is explicitly allowed by the Standard.  On the
other hand, no warning is issued for the GOTO 20, which is outside of
the IF-THEN-ENDIF block with the labeled '20 END IF'.

I've been unable to penetrate the logic of the bitmap stuff in 
resolve_branch, thus the cc to Tobi.


2008-12-14  Steven G. Kargl  <kargls@comcast.net>

	PR fortran/38507
	* gfortran.dg/goto_4.f90:  Update test program.

2008-12-14  Steven G. Kargl  <kargls@comcast.net>

	PR fortran/38507
	*resolve.c:  Remove bogus warning on GOTOs to END DO.

-- 
Steve
Index: gcc/testsuite/gfortran.dg/goto_4.f90
===================================================================
--- gcc/testsuite/gfortran.dg/goto_4.f90	(revision 142737)
+++ gcc/testsuite/gfortran.dg/goto_4.f90	(working copy)
@@ -1,10 +1,16 @@
 ! { dg-do run }
-! PR 17708: Jumping to END DO statements didn't do the right thing
+! PR 17708: Jumping to END DO statements didn't do the right thing.
+!
+! PR 38507: Adjust the testcase to reflect that the standard allows
+! one to jump to the END DO from within a do-loop.  The behavior is
+! equivalent to CYCLE.  Note, the warning has been removed.
+!
       program test
-        j = 0
+        integer i, n(3)
+        n = 42
         do 10 i=1,3
-           if(i == 2) goto 10 ! { dg-warning "jumps to END" }
-           j = j+1
-10      enddo                 ! { dg-warning "jumps to END" }
-        if (j/=2) call abort
-      end
+           if(i == 2) goto 10
+           n(i) = i
+10      end do
+        if (any(n /= (/ 1, 42, 3 /))) call abort
+      end program test
Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(revision 142737)
+++ gcc/fortran/resolve.c	(working copy)
@@ -6042,21 +6042,6 @@ resolve_branch (gfc_st_label *label, gfc
 		      &stack->current->next->loc);
       return;  /* We know this is not an END DO.  */
     }
-
-  /* Step five: Make sure that we're not jumping to the end of a DO
-     loop from within the loop.  */
-
-  for (stack = cs_base; stack; stack = stack->prev)
-    if ((stack->current->op == EXEC_DO
-	 || stack->current->op == EXEC_DO_WHILE)
-	&& stack->tail->here == label && stack->tail->op == EXEC_NOP)
-      {
-	gfc_notify_std (GFC_STD_F95_DEL, "Deleted feature: GOTO at %L jumps "
-			"to END of construct at %L", &code->loc,
-			&stack->tail->loc);
-	return;
-
-      }
 }
 
 

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