[PATCH, fortran] PR 38507 -- goto to end do is legal.

Tobias Schlüter tobias.schlueter@physik.uni-muenchen.de
Sun Dec 14 22:54:00 GMT 2008


Hi Steve,

Steve Kargl wrote:
> 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.

Indeed, looking at the October 97 draft I read:
8.1.4.2 Range of the DO construct
The range of a block DO construct is the do-block, which shall satisfy 
the rules for blocks (8.1.1).  In particular, transfer of control to the 
interior of such a block from outside the block is prohibited.  It is 
permitted to branch to the end-do of a block DO construct only from 
within the range of that DO construct.

… which is in direct conflict with what I implemented.  I wonder what I 
was thinking, as I even mentioned END DO as a problematic special case 
in one of the original PRs.

> 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.

It is actually very simple: each block has a bitmap which is a set 
saying which label numbers are in each block.  For each contained block 
the valid labels for a GO TO (or ERR descriptor in I/O) are the union of 
the labels reachable from the containing block and the labels inside the 
block itself (i.e. the inclusive bitwise OR of the bitmaps).  Now in the 
PRs you mentioned that END IF and END DO are handled differently, namely 
END DO is part of the contained block, END IF is part of the containing 
block.  If END IF were part of the contained block, then the error for 
the deleted gotos were automatic.

As for your patch, END DO is mentioned as a special case right above the 
code you're removing.  You should probably update that comment along the 
way.

Cheers,
- Tobi



More information about the Gcc-patches mailing list