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;