re PR fortran/44847 (ICE: OpenMP with Collapse clause and CYCLE stmt in loop)
authorJakub Jelinek <jakub@redhat.com>
Thu, 8 Jul 2010 17:30:41 +0000 (19:30 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 8 Jul 2010 17:30:41 +0000 (19:30 +0200)
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.

From-SVN: r161967

gcc/fortran/ChangeLog
gcc/fortran/match.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/gomp/pr44847.f90 [new file with mode: 0644]

index 34dff477b06276d4ed150686c0211e44f145994b..34ce90c2d769e2361a53a5c90600c44078e5193f 100644 (file)
@@ -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
index 92c4da0a4b5a9376edbcceeb26084e970413507c..a51d24c65686df91eb5a26a01f6433c7d5837489 100644 (file)
@@ -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.  */
index 776f8bc5657740cb58f96955f9de10ad2342b201..2ed315e1cf02a322ba235c7a5b73e3e753c5783a 100644 (file)
@@ -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 (file)
index 0000000..3da4311
--- /dev/null
@@ -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