Bug 44602 - [F2008] EXIT: Jump to end of construct
Summary: [F2008] EXIT: Jump to end of construct
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: ---
Assignee: Daniel Kraft
URL:
Keywords:
Depends on: 44709
Blocks: 39627
  Show dependency treegraph
 
Reported: 2010-06-20 19:58 UTC by Tobias Burnus
Modified: 2010-09-03 08:04 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2010-08-30 12:07:54


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2010-06-20 19:58:46 UTC
Fortran 2003 only had:
   R844 exit-stmt is EXIT [ do-construct-name ]
while Fortran 2008 (FDIS) has:
   R850 exit-stmt is EXIT [ construct-name ]

While with "EXIT" one only exits the innermost construct, F2008 also allows to exit other constructs; looking at 8.1 one finds the following constructs:
- ASSOCIATE
- BLOCK
- CRITICAL
- DO
- IF
- SELECT CASE
- SELECT TYPE

of which in CRITICAL and DO CONCURRENT it is invalid to jump to their construct label (or outside the construct) cf. C845. This is already checked for CRITICAL.
Comment 1 Tobias Burnus 2010-06-20 20:52:27 UTC
See below for a match.c patch. However, it will fail as the labels are not available. In principle, one just needs to add:

  tree exit_label;
  /* The exit label.  */
  exit_label = gfc_build_label_decl (NULL_TREE);
  code->block->backend_decl = tree_cons (NULL, exit_label, NULL);
  stmt = build1_v (LABEL_EXPR, exit_label);
  gfc_add_expr_to_block (&if_se.pre, stmt);

to all constructs (in trans-stmt.c) as then trans_exit's

  exit_label = TREE_VALUE (code->ext.whichloop->backend_decl);

would work. However, this fails for instance for the IF block as there "code->block" is only available if an ELSE branch exists.


Index: match.c
===================================================================
--- match.c     (Revision 161045)
+++ match.c
@@ -2034,6 +2034,13 @@ match_exit_cycle
                  gfc_ascii_statement (st));
        return MATCH_ERROR;
       }
+    else if (sym == p->sym)
+      {
+       if (gfc_notify_std (GFC_STD_F2008, "Fortran 2008: EXIT with no "
+                           "do-construct-name at %C") == FAILURE)
+         return MATCH_ERROR;
+       break;
+      }
 
   if (p == NULL)
     {
@@ -2041,7 +2048,7 @@
        gfc_error ("%s statement at %C is not within a loop",
                   gfc_ascii_statement (st));
       else
-       gfc_error ("%s statement at %C is not within loop '%s'",
+       gfc_error ("%s statement at %C is not within construct '%s'",
                   gfc_ascii_statement (st), sym->name);
 
       return MATCH_ERROR;
Comment 2 Tobias Burnus 2010-06-21 07:41:20 UTC
+    else if (sym == p->sym)

One should check that this does the right thing for
  do
    block
      exit
    end block
  end do
as this should leave the DO construct and not only the BLOCK construct (to be compatible with older Fortran standard, where EXIT was relative to DO).
Comment 3 Tobias Burnus 2010-07-23 08:55:49 UTC
PR 44709 comment 0 contains a small test case, which also applies here.

(That PR fixed "exit loop_label" in BLOCK and try-finally cleanup in BLOCK.)
Comment 4 Daniel Kraft 2010-08-30 12:07:54 UTC
Mine.
Comment 5 Daniel Kraft 2010-08-30 18:27:04 UTC
Experimental patch here: http://gcc.gnu.org/ml/fortran/2010-08/msg00456.html

It seems to do what it is supposed to (basically) and also runs the full test-case of PR 44709 comment 0, but there seems to be at least one regression to work out.
Comment 6 Daniel Kraft 2010-09-03 08:02:09 UTC
Subject: Bug 44602

Author: domob
Date: Fri Sep  3 08:01:51 2010
New Revision: 163798

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=163798
Log:
2010-09-03  Daniel Kraft  <d@domob.eu>

	PR fortran/44602
	* gfortran.h (struct gfc_code): Renamed `whichloop' to
	`which_construct' as this is no longer restricted to loops.
	* parse.h (struct gfc_state_data): New field `construct'.
	* match.c (match_exit_cycle): Handle EXIT from non-loops.
	* parse.c (push_state): Set `construct' field.
	* resolve.c (resolve_select_type): Extend comment.
	* trans-stmt.c (gfc_trans_if): Add exit label.
	(gfc_trans_block_construct), (gfc_trans_select): Ditto.
	(gfc_trans_simple_do): Store exit/cycle labels on the gfc_code itself.
	(gfc_trans_do), (gfc_trans_do_while): Ditto.
	(gfc_trans_exit): Use new name `which_construct' instead of `whichloop'.
	(gfc_trans_cycle): Ditto.
	(gfc_trans_if_1): Use fold_build3_loc instead of fold_build3.

2010-09-03  Daniel Kraft  <d@domob.eu>

	PR fortran/44602
	* gfortran.dg/exit_2.f08; Adapt error messages.
	* gfortran.dg/exit_3.f08: New test.
	* gfortran.dg/exit_4.f08: New test.
	* gfortran.dg/exit_5.f03: New test.

Added:
    trunk/gcc/testsuite/gfortran.dg/exit_3.f08
    trunk/gcc/testsuite/gfortran.dg/exit_4.f08
    trunk/gcc/testsuite/gfortran.dg/exit_5.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/match.c
    trunk/gcc/fortran/parse.c
    trunk/gcc/fortran/parse.h
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/trans-stmt.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/exit_2.f08

Comment 7 Daniel Kraft 2010-09-03 08:04:30 UTC
Fixed.