http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38312
--- Comment #6 from Steve Kargl <sgk at troutmask dot apl.washington.edu> 2011-11-12 22:41:06 UTC --- On Sat, Nov 12, 2011 at 10:03:49PM +0000, kargl at gcc dot gnu.org wrote: > > --- Comment #5 from kargl at gcc dot gnu.org 2011-11-12 22:03:49 UTC --- > I've looked at this issue, and I have come to the conclusion > that it should be closed as WONTFIX. First, an error is > issued, so one can fix their Fortran code. > > Now, for the problem. The matchers are called from the > parser according this diagram (parse.c line 1717). > > +---------------------------------------+ > | program subroutine function module | > +---------------------------------------+ > | use | > +---------------------------------------+ > | import | > +---------------------------------------+ > | | implicit none | > | +-----------+-----------------+ > | | parameter | implicit | > | +-----------+-----------------+ > | format | | derived type | > | entry | parameter | interface | > | | data | specification | > | | | statement func | > | +-----------+-----------------+ > | | data | executable | > +---------+-----------+-----------------+ > | contains | > +---------------------------------------+ > | internal module/subprogram | > +---------------------------------------+ > | end | > +---------------------------------------+ > > As one can see, a DATA statement and a statement function are > parsed at the same level. A programmer can use an implied > do-loop within a DATA statement. Unfortunately, an implied > do-loop is parsed by the same code that parses a regular > do-loop. It appears that insufficient information is contained > within the parser at the point where the error is issued > to determine that the do-loop is in an executable portion of > the program. > I can generate laptop:kargl[230] gfc4x -c foo.f90 foo.f90:6.19: co(i)=t1(i)*2 1 Warning: Line at (1) parsed as a STATEMENT FUNCTION foo.f90:6.8: co(i)=t1(i)*2 1 Error: Variable type is UNKNOWN in assignment at (1) with this very ugly kludge. Index: parse.c =================================================================== --- parse.c (revision 181307) +++ parse.c (working copy) @@ -1723,30 +1723,30 @@ unexpected_statement (gfc_statement st) valid before calling here, i.e., ENTRY statements are not allowed in INTERFACE blocks. The following diagram is taken from the standard: - +---------------------------------------+ - | program subroutine function module | - +---------------------------------------+ - | use | - +---------------------------------------+ - | import | - +---------------------------------------+ - | | implicit none | - | +-----------+------------------+ - | | parameter | implicit | - | +-----------+------------------+ - | format | | derived type | - | entry | parameter | interface | - | | data | specification | - | | | statement func | - | +-----------+------------------+ - | | data | executable | - +--------+-----------+------------------+ - | contains | - +---------------------------------------+ - | internal module/subprogram | - +---------------------------------------+ - | end | - +---------------------------------------+ + +---------------------------------------+ + | program subroutine function module | + +---------------------------------------+ + | use | + +---------------------------------------+ + | import | + +---------------------------------------+ + | | implicit none | + | +-----------+-----------------+ + | | parameter | implicit | + | +-----------+-----------------+ + | format | | derived type | + | entry | parameter | interface | + | | data | specification | + | | | statement func | + | +-----------+-----------------+ + | | data | executable | + +---------+-----------+-----------------+ + | contains | + +---------------------------------------+ + | internal module/subprogram | + +---------------------------------------+ + | end | + +---------------------------------------+ */ @@ -3381,7 +3381,10 @@ loop: handled inside of parse_executable(), because they aren't really loop statements. */ -static void +static bool in_execute_state; +void parse_do_block (void); + +void parse_do_block (void) { gfc_statement st; @@ -3442,7 +3445,13 @@ loop: break; default: - unexpected_statement (st); + if (!in_execute_state) + unexpected_statement (st); + else + { + gfc_warning ("Line at %C parsed as a STATEMENT FUNCTION"); + accept_statement (ST_ASSIGNMENT); + } goto loop; } @@ -3810,7 +3819,9 @@ parse_executable (gfc_statement st) break; case ST_DO: + in_execute_state = true; parse_do_block (); + in_execute_state = false; if (check_do_closure () == 1) return ST_IMPLIED_ENDDO; break;