summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-08 17:30:41 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-08 17:30:41 +0000
commit7297507e8b901fe4fecf1282fc09d32a85712129 (patch)
tree895fe9745b208895dd570c4684446e8536a6eb42
parent69b18a8b03bc8cb57e9489f77da45dcab39c415c (diff)
downloadgcc-7297507e8b901fe4fecf1282fc09d32a85712129.tar.gz
PR fortran/44847
* match.c (match_exit_cycle): Error on EXIT also from collapsed !$omp do loops. Error on CYCLE to non-innermost collapsed !$omp do loops. * gfortran.dg/gomp/pr44847.f90: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161967 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/fortran/ChangeLog7
-rw-r--r--gcc/fortran/match.c42
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/pr44847.f9086
4 files changed, 128 insertions, 12 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 34dff477b06..34ce90c2d76 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,10 @@
+2010-07-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/44847
+ * match.c (match_exit_cycle): Error on EXIT also from collapsed
+ !$omp do loops. Error on CYCLE to non-innermost collapsed
+ !$omp do loops.
+
2010-07-08 Tobias Burnus <burnus@net-b.de>
PR fortran/18918
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 92c4da0a4b5..a51d24c6568 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -2000,6 +2000,7 @@ match_exit_cycle (gfc_statement st, gfc_exec_op op)
gfc_state_data *p, *o;
gfc_symbol *sym;
match m;
+ int cnt;
if (gfc_match_eos () == MATCH_YES)
sym = NULL;
@@ -2022,7 +2023,7 @@ match_exit_cycle (gfc_statement st, gfc_exec_op op)
}
}
- /* Find the loop mentioned specified by the label (or lack of a label). */
+ /* Find the loop specified by the label (or lack of a label). */
for (o = NULL, p = gfc_state_stack; p; p = p->previous)
if (p->state == COMP_DO && (sym == NULL || sym == p->sym))
break;
@@ -2053,17 +2054,34 @@ match_exit_cycle (gfc_statement st, gfc_exec_op op)
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;
+
+ for (o = p, cnt = 0; o->state == COMP_DO && o->previous != NULL; cnt++)
+ o = o->previous;
+ if (cnt > 0
+ && o != NULL
+ && o->state == COMP_OMP_STRUCTURED_BLOCK
+ && (o->head->op == EXEC_OMP_DO
+ || o->head->op == EXEC_OMP_PARALLEL_DO))
+ {
+ int collapse = 1;
+ gcc_assert (o->head->next != NULL
+ && (o->head->next->op == EXEC_DO
+ || o->head->next->op == EXEC_DO_WHILE)
+ && o->previous != NULL
+ && o->previous->tail->op == o->head->op);
+ if (o->previous->tail->ext.omp_clauses != NULL
+ && o->previous->tail->ext.omp_clauses->collapse > 1)
+ collapse = o->previous->tail->ext.omp_clauses->collapse;
+ if (st == ST_EXIT && cnt <= collapse)
+ {
+ gfc_error ("EXIT statement at %C terminating !$OMP DO loop");
+ return MATCH_ERROR;
+ }
+ if (st == ST_CYCLE && cnt < collapse)
+ {
+ gfc_error ("CYCLE statement at %C to non-innermost collapsed !$OMP DO loop");
+ return MATCH_ERROR;
+ }
}
/* Save the first statement in the loop - needed by the backend. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 776f8bc5657..2ed315e1cf0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-07-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/44847
+ * gfortran.dg/gomp/pr44847.f90: New test.
+
2010-07-08 Sebastian Pop <sebastian.pop@amd.com>
PR tree-optimization/44710
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr44847.f90 b/gcc/testsuite/gfortran.dg/gomp/pr44847.f90
new file mode 100644
index 00000000000..3da4311499e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr44847.f90
@@ -0,0 +1,86 @@
+! PR fortran/44847
+! { dg-do compile }
+! { dg-options "-fopenmp" }
+
+subroutine pr44847_1
+ integer :: i, j
+!$omp parallel do collapse(2)
+l:do i = 1, 2
+ do j = 1, 2
+ cycle l ! { dg-error "CYCLE statement" }
+ end do
+ end do l
+end subroutine
+subroutine pr44847_2
+ integer :: i, j, k
+!$omp parallel do collapse(3)
+ do i = 1, 2
+ l:do j = 1, 2
+ do k = 1, 2
+ cycle l ! { dg-error "CYCLE statement" }
+ end do
+ end do l
+ end do
+end subroutine
+subroutine pr44847_3
+ integer :: i, j
+!$omp parallel do
+l:do i = 1, 2
+ do j = 1, 2
+ cycle l
+ end do
+ end do l
+end subroutine
+subroutine pr44847_4
+ integer :: i, j, k
+!$omp parallel do collapse(2)
+ do i = 1, 2
+ l:do j = 1, 2
+ do k = 1, 2
+ cycle l
+ end do
+ end do l
+ end do
+end subroutine
+subroutine pr44847_5
+ integer :: i, j
+!$omp parallel do collapse(2)
+l:do i = 1, 2
+ do j = 1, 2
+ exit l ! { dg-error "EXIT statement" }
+ end do
+ end do l
+end subroutine
+subroutine pr44847_6
+ integer :: i, j, k
+!$omp parallel do collapse(3)
+ do i = 1, 2
+ l:do j = 1, 2
+ do k = 1, 2
+ exit l ! { dg-error "EXIT statement" }
+ end do
+ end do l
+ end do
+end subroutine
+subroutine pr44847_7
+ integer :: i, j, k
+!$omp parallel do collapse(2)
+ do i = 1, 2
+ l:do j = 1, 2
+ do k = 1, 2
+ exit l ! { dg-error "EXIT statement" }
+ end do
+ end do l
+ end do
+end subroutine
+subroutine pr44847_8
+ integer :: i, j, k
+!$omp parallel do
+ do i = 1, 2
+ l:do j = 1, 2
+ do k = 1, 2
+ exit l
+ end do
+ end do l
+ end do
+end subroutine