diff options
Diffstat (limited to 'gcc/fortran/match.c')
| -rw-r--r-- | gcc/fortran/match.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c index a78cd028ea4..a2b9c41d549 100644 --- a/gcc/fortran/match.c +++ b/gcc/fortran/match.c @@ -1341,7 +1341,7 @@ cleanup: static match match_exit_cycle (gfc_statement st, gfc_exec_op op) { - gfc_state_data *p; + gfc_state_data *p, *o; gfc_symbol *sym; match m; @@ -1368,9 +1368,11 @@ match_exit_cycle (gfc_statement st, gfc_exec_op op) /* Find the loop mentioned specified by the label (or lack of a label). */ - for (p = gfc_state_stack; p; p = p->previous) + for (o = NULL, p = gfc_state_stack; p; p = p->previous) if (p->state == COMP_DO && (sym == NULL || sym == p->sym)) break; + else if (o == NULL && p->state == COMP_OMP_STRUCTURED_BLOCK) + o = p; if (p == NULL) { @@ -1384,6 +1386,25 @@ match_exit_cycle (gfc_statement st, gfc_exec_op op) return MATCH_ERROR; } + if (o != NULL) + { + gfc_error ("%s statement at %C leaving OpenMP structured block", + gfc_ascii_statement (st)); + return MATCH_ERROR; + } + else if (st == ST_EXIT + && p->previous != NULL + && p->previous->state == COMP_OMP_STRUCTURED_BLOCK + && (p->previous->head->op == EXEC_OMP_DO + || p->previous->head->op == EXEC_OMP_PARALLEL_DO)) + { + gcc_assert (p->previous->head->next != NULL); + gcc_assert (p->previous->head->next->op == EXEC_DO + || p->previous->head->next->op == EXEC_DO_WHILE); + gfc_error ("EXIT statement at %C terminating !$OMP DO loop"); + return MATCH_ERROR; + } + /* Save the first statement in the loop - needed by the backend. */ new_st.ext.whichloop = p->head; |

