Hi!

The omp_code_to_statement function added with the initial OpenACC support
only handled small subset of the OpenMP statements, leading to ICE if
any other OpenMP directive appeared inside of OpenACC directive.

The following patch teaches it to handle the rest and adds testcase that
verifies that, bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk.

2020-01-22  Jakub Jelinek  <ja...@redhat.com>

        PR fortran/93329
        * openmp.c (omp_code_to_statement): Handle remaining EXEC_OMP_*
        cases.

        * gfortran.dg/goacc/pr93329.f90: New test.

--- gcc/fortran/openmp.c.jj     2020-01-12 11:54:36.594410678 +0100
+++ gcc/fortran/openmp.c        2020-01-21 16:05:21.271520015 +0100
@@ -5898,6 +5898,81 @@ omp_code_to_statement (gfc_code *code)
       return ST_OMP_PARALLEL_WORKSHARE;
     case EXEC_OMP_DO:
       return ST_OMP_DO;
+    case EXEC_OMP_ATOMIC:
+      return ST_OMP_ATOMIC;
+    case EXEC_OMP_BARRIER:
+      return ST_OMP_BARRIER;
+    case EXEC_OMP_CANCEL:
+      return ST_OMP_CANCEL;
+    case EXEC_OMP_CANCELLATION_POINT:
+      return ST_OMP_CANCELLATION_POINT;
+    case EXEC_OMP_FLUSH:
+      return ST_OMP_FLUSH;
+    case EXEC_OMP_DISTRIBUTE:
+      return ST_OMP_DISTRIBUTE;
+    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
+      return ST_OMP_DISTRIBUTE_PARALLEL_DO;
+    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
+      return ST_OMP_DISTRIBUTE_PARALLEL_DO_SIMD;
+    case EXEC_OMP_DISTRIBUTE_SIMD:
+      return ST_OMP_DISTRIBUTE_SIMD;
+    case EXEC_OMP_DO_SIMD:
+      return ST_OMP_DO_SIMD;
+    case EXEC_OMP_SIMD:
+      return ST_OMP_SIMD;
+    case EXEC_OMP_TARGET:
+      return ST_OMP_TARGET;
+    case EXEC_OMP_TARGET_DATA:
+      return ST_OMP_TARGET_DATA;
+    case EXEC_OMP_TARGET_ENTER_DATA:
+      return ST_OMP_TARGET_ENTER_DATA;
+    case EXEC_OMP_TARGET_EXIT_DATA:
+      return ST_OMP_TARGET_EXIT_DATA;
+    case EXEC_OMP_TARGET_PARALLEL:
+      return ST_OMP_TARGET_PARALLEL;
+    case EXEC_OMP_TARGET_PARALLEL_DO:
+      return ST_OMP_TARGET_PARALLEL_DO;
+    case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
+      return ST_OMP_TARGET_PARALLEL_DO_SIMD;
+    case EXEC_OMP_TARGET_SIMD:
+      return ST_OMP_TARGET_SIMD;
+    case EXEC_OMP_TARGET_TEAMS:
+      return ST_OMP_TARGET_TEAMS;
+    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
+      return ST_OMP_TARGET_TEAMS_DISTRIBUTE;
+    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
+      return ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO;
+    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
+      return ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD;
+    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
+      return ST_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD;
+    case EXEC_OMP_TARGET_UPDATE:
+      return ST_OMP_TARGET_UPDATE;
+    case EXEC_OMP_TASKGROUP:
+      return ST_OMP_TASKGROUP;
+    case EXEC_OMP_TASKLOOP:
+      return ST_OMP_TASKLOOP;
+    case EXEC_OMP_TASKLOOP_SIMD:
+      return ST_OMP_TASKLOOP_SIMD;
+    case EXEC_OMP_TASKWAIT:
+      return ST_OMP_TASKWAIT;
+    case EXEC_OMP_TASKYIELD:
+      return ST_OMP_TASKYIELD;
+    case EXEC_OMP_TEAMS:
+      return ST_OMP_TEAMS;
+    case EXEC_OMP_TEAMS_DISTRIBUTE:
+      return ST_OMP_TEAMS_DISTRIBUTE;
+    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
+      return ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO;
+    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
+      return ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD;
+    case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
+      return ST_OMP_TEAMS_DISTRIBUTE_SIMD;
+    case EXEC_OMP_PARALLEL_DO:
+      return ST_OMP_PARALLEL_DO;
+    case EXEC_OMP_PARALLEL_DO_SIMD:
+      return ST_OMP_PARALLEL_DO_SIMD;
+
     default:
       gcc_unreachable ();
     }
--- gcc/testsuite/gfortran.dg/goacc/pr93329.f90.jj      2020-01-21 
16:33:13.235417921 +0100
+++ gcc/testsuite/gfortran.dg/goacc/pr93329.f90 2020-01-21 16:33:03.043571159 
+0100
@@ -0,0 +1,223 @@
+! PR fortran/93329
+! { dg-do compile { target fopenmp } }
+! { dg-additional-options "-fopenmp" }
+
+  integer :: x, y, z
+  integer :: a(32)
+!$acc kernels copyout(x)
+!$omp target map(from:x)       ! { dg-error "OMP TARGET directive cannot be 
specified within" }
+  x = 5
+!$omp end target
+!$acc end kernels
+  print *, x
+!$acc kernels
+!$omp atomic                   ! { dg-error "OMP ATOMIC directive cannot be 
specified within" }
+  x = x + 1
+!$omp end atomic
+!$acc end kernels
+!$acc kernels
+!$omp barrier                  ! { dg-error "OMP BARRIER directive cannot be 
specified within" }
+!$acc end kernels
+!$acc kernels
+!$omp cancel parallel          ! { dg-error "OMP CANCEL directive cannot be 
specified within" }
+!$acc end kernels
+!$acc kernels
+!$omp cancellation point parallel      ! { dg-error "OMP CANCELLATION POINT 
directive cannot be specified within" }
+!$acc end kernels
+!$acc kernels
+!$omp flush                    ! { dg-error "OMP FLUSH directive cannot be 
specified within" }
+!$acc end kernels
+!$acc kernels
+!$omp distribute               ! { dg-error "OMP DISTRIBUTE directive cannot 
be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp distribute parallel do   ! { dg-error "OMP DISTRIBUTE PARALLEL DO 
directive cannot be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp distribute parallel do simd      ! { dg-error "OMP DISTRIBUTE PARALLEL 
DO SIMD directive cannot be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp distribute simd          ! { dg-error "OMP DISTRIBUTE SIMD directive 
cannot be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp do simd                  ! { dg-error "OMP DO SIMD directive cannot be 
specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp simd                     ! { dg-error "OMP SIMD directive cannot be 
specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp target data map(from: x) ! { dg-error "OMP TARGET DATA directive cannot 
be specified within" }
+!$omp end target data
+!$acc end kernels
+!$acc kernels
+!$omp target enter data map(to: x)     ! { dg-error "OMP TARGET ENTER DATA 
directive cannot be specified within" }
+!$acc end kernels
+!$acc kernels
+!$omp target exit data map(from: x)    ! { dg-error "OMP TARGET EXIT DATA 
directive cannot be specified within" }
+!$acc end kernels
+!$acc kernels
+!!$omp target parallel
+!!$omp end target parallel
+!$acc end kernels
+!$acc kernels
+!$omp target parallel do       ! { dg-error "OMP TARGET PARALLEL DO directive 
cannot be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp target parallel do simd  ! { dg-error "OMP TARGET PARALLEL DO SIMD 
directive cannot be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp target simd              ! { dg-error "OMP TARGET SIMD directive cannot 
be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp target teams             ! { dg-error "OMP TARGET TEAMS directive cannot 
be specified within" }
+!$omp end target teams
+!$acc end kernels
+!$acc kernels
+!$omp target teams distribute  ! { dg-error "OMP TARGET TEAMS DISTRIBUTE 
directive cannot be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp target teams distribute parallel do      ! { dg-error "OMP TARGET TEAMS 
DISTRIBUTE PARALLEL DO directive cannot be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp target teams distribute parallel do simd ! { dg-error "OMP TARGET TEAMS 
DISTRIBUTE PARALLEL DO SIMD directive cannot be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp target teams distribute simd     ! { dg-error "OMP TARGET TEAMS 
DISTRIBUTE SIMD directive cannot be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp target update to(x)      ! { dg-error "OMP TARGET UPDATE directive 
cannot be specified within" }
+!$acc end kernels
+!$acc kernels
+!$omp taskgroup                        ! { dg-error "OMP TASKGROUP directive 
cannot be specified within" }
+!$omp end taskgroup
+!$acc end kernels
+!$acc kernels
+!$omp taskloop                 ! { dg-error "OMP TASKLOOP directive cannot be 
specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp taskloop simd            ! { dg-error "OMP TASKLOOP SIMD directive 
cannot be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp taskwait                 ! { dg-error "OMP TASKWAIT directive cannot be 
specified within" }
+!$acc end kernels
+!$acc kernels
+!$omp taskyield                        ! { dg-error "OMP TASKYIELD directive 
cannot be specified within" }
+!$acc end kernels
+!$acc kernels
+!$omp teams                    ! { dg-error "OMP TEAMS directive cannot be 
specified within" }
+!$omp end teams
+!$acc end kernels
+!$acc kernels
+!$omp teams distribute         ! { dg-error "OMP TEAMS DISTRIBUTE directive 
cannot be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp teams distribute parallel do     ! { dg-error "OMP TEAMS DISTRIBUTE 
PARALLEL DO directive cannot be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp teams distribute parallel do simd        ! { dg-error "OMP TEAMS 
DISTRIBUTE PARALLEL DO SIMD directive cannot be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp teams distribute simd    ! { dg-error "OMP TEAMS DISTRIBUTE SIMD 
directive cannot be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp parallel do              ! { dg-error "OMP PARALLEL DO directive cannot 
be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp parallel do simd         ! { dg-error "OMP PARALLEL DO SIMD directive 
cannot be specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+!$acc kernels
+!$omp parallel                 ! { dg-error "OMP PARALLEL directive cannot be 
specified within" }
+!$omp end parallel
+!$acc end kernels
+!$acc kernels
+!$omp parallel sections                ! { dg-error "OMP PARALLEL SECTIONS 
directive cannot be specified within" }
+  y = 1
+!$omp section
+  z = 2
+!$omp end parallel sections
+!$acc end kernels
+!$acc kernels
+!$omp sections                 ! { dg-error "OMP SECTIONS directive cannot be 
specified within" }
+  y = 1
+!$omp section
+  z = 2
+!$omp end sections
+!$acc end kernels
+!$acc kernels
+!$omp ordered                  ! { dg-error "OMP ORDERED directive cannot be 
specified within" }
+!$omp end ordered
+!$acc end kernels
+!$acc kernels
+!$omp critical                 ! { dg-error "OMP CRITICAL directive cannot be 
specified within" }
+!$omp end critical
+!$acc end kernels
+!$acc kernels
+!$omp master                   ! { dg-error "OMP MASTER directive cannot be 
specified within" }
+!$omp end master
+!$acc end kernels
+!$acc kernels
+!$omp single                   ! { dg-error "OMP SINGLE directive cannot be 
specified within" }
+!$omp end single
+!$acc end kernels
+!$acc kernels
+!$omp task                     ! { dg-error "OMP TASK directive cannot be 
specified within" }
+!$omp end task
+!$acc end kernels
+!$acc kernels
+!$omp workshare                        ! { dg-error "OMP WORKSHARE directive 
cannot be specified within" }
+  a(:) = 1
+!$omp end workshare
+!$acc end kernels
+!$acc kernels
+!$omp parallel workshare       ! { dg-error "OMP PARALLEL WORKSHARE directive 
cannot be specified within" }
+  a(:) = 1
+!$omp end parallel workshare
+!$acc end kernels
+!$acc kernels
+!$omp do                       ! { dg-error "OMP DO directive cannot be 
specified within" }
+  do x = 0, 2
+  end do
+!$acc end kernels
+end

        Jakub

Reply via email to