Hi all, hi Jakub & Thomas,

I did run into this issue with the previous patch where

!$omp  parallel &
!$acc& loop

did no longer report an error – hence, I changed 'loop' to 'kernels loop'
as buffered 'gfc_error' might not be output.

Having no error is very unfortunate.
There is no ideal solution for the problem, but I think the
attached patch makes sense.

I now include the original version besides the patch version of
the 'parallel' / '(kernels )loop' test.


This patch now does:

* For Fortran's free source form:
  - use 'gfc_error_now' to ensure an error is printed
  - cache the error location such that the same error is not
    shown multiple times
  - Return '\n' to avoid parsing the code again.

* For Fortran's fixed source form:
  - Likewise
Except:
!$OMP  ...
!$ACC  ...
Here, '!$ACC ' is not a continuation line! Not even when
placing a '&' in column > 72 (as those columns are ignored).
Thus, handle this !$ACC as separate statement.


SIDE EFFECT: Due to returning '\n', the parsing of
 !$OMP parallel &
 !$ACC LOOP
now succeeds: '!$OMP parallel' + '!$ACC LOOP' - such that
the rest of the syntax/semantic rules apply.

Thus, (after printing the gfc_error_now), gfortran continues and
- there is now the resolution-time error about invalid nesting of OMP/ACC
- the '!$OMP parallel' now requires an '!$OMP end parallel' to avoid
  parsing errors.


OK? More comments?

Tobias

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf
Fortran: Fix OpenMP/OpenACC continue-line parsing

gcc/fortran/ChangeLog:

	* scanner.c (skip_fixed_omp_sentinel): Set openacc_flag if
	this is not an (OpenMP) continuation line.
	(skip_fixed_oacc_sentinel): Likewise for openmp_flag and OpenACC.
	(gfc_next_char_literal): gfc_error_now to force error for mixed OMP/ACC
	continuation once per location and return '\n'.

gcc/testsuite/ChangeLog:

	* gfortran.dg/goacc/omp-fixed.f: Re-add test item changed in previous
	commit in addition - add more dg-errors and '... end ...' due to changed
	parsing.
	* gfortran.dg/goacc/omp.f95: Likewise.
	* gfortran.dg/goacc-gomp/mixed-1.f: New test.

 gcc/fortran/scanner.c                          | 35 +++++++++++++++++---------
 gcc/testsuite/gfortran.dg/goacc-gomp/mixed-1.f | 23 +++++++++++++++++
 gcc/testsuite/gfortran.dg/goacc/omp-fixed.f    | 10 +++++++-
 gcc/testsuite/gfortran.dg/goacc/omp.f95        | 12 +++++++++
 4 files changed, 67 insertions(+), 13 deletions(-)

diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c
index 74c5461ed6f..39db0994b62 100644
--- a/gcc/fortran/scanner.c
+++ b/gcc/fortran/scanner.c
@@ -942,6 +942,8 @@ skip_fixed_omp_sentinel (locus *start)
 	  && (continue_flag
 	      || c == ' ' || c == '\t' || c == '0'))
 	{
+	  if (c == ' ' || c == '\t' || c == '0')
+	    openacc_flag = 0;
 	  do
 	    c = next_char ();
 	  while (gfc_is_whitespace (c));
@@ -971,6 +973,8 @@ skip_fixed_oacc_sentinel (locus *start)
 	  && (continue_flag
 	      || c == ' ' || c == '\t' || c == '0'))
 	{
+	  if (c == ' ' || c == '\t' || c == '0')
+	    openmp_flag = 0;
 	  do
 	    c = next_char ();
 	  while (gfc_is_whitespace (c));
@@ -1205,6 +1209,7 @@ gfc_skip_comments (void)
 gfc_char_t
 gfc_next_char_literal (gfc_instring in_string)
 {
+  static locus omp_acc_err_loc = {};
   locus old_loc;
   int i, prev_openmp_flag, prev_openacc_flag;
   gfc_char_t c;
@@ -1403,14 +1408,16 @@ restart:
 	    {
 	      if (gfc_wide_tolower (c) != (unsigned char) "!$acc"[i])
 		is_openmp = 1;
-	      if (i == 4)
-		old_loc = gfc_current_locus;
 	    }
-	  gfc_error (is_openmp
-		     ? G_("Wrong OpenACC continuation at %C: "
-			  "expected !$ACC, got !$OMP")
-		     : G_("Wrong OpenMP continuation at %C: "
-			  "expected !$OMP, got !$ACC"));
+	  if (omp_acc_err_loc.nextc != gfc_current_locus.nextc
+	      || omp_acc_err_loc.lb != gfc_current_locus.lb)
+	    gfc_error_now (is_openmp
+			   ? G_("Wrong OpenACC continuation at %C: "
+				"expected !$ACC, got !$OMP")
+			   : G_("Wrong OpenMP continuation at %C: "
+				"expected !$OMP, got !$ACC"));
+	  omp_acc_err_loc = gfc_current_locus;
+	  goto not_continuation;
 	}
 
       if (c != '&')
@@ -1511,11 +1518,15 @@ restart:
 	      if (gfc_wide_tolower (c) != (unsigned char) "*$acc"[i])
 		is_openmp = 1;
 	    }
-	  gfc_error (is_openmp
-		     ? G_("Wrong OpenACC continuation at %C: "
-			  "expected !$ACC, got !$OMP")
-		     : G_("Wrong OpenMP continuation at %C: "
-			  "expected !$OMP, got !$ACC"));
+	  if (omp_acc_err_loc.nextc != gfc_current_locus.nextc
+	      || omp_acc_err_loc.lb != gfc_current_locus.lb)
+	    gfc_error_now (is_openmp
+			   ? G_("Wrong OpenACC continuation at %C: "
+				"expected !$ACC, got !$OMP")
+			   : G_("Wrong OpenMP continuation at %C: "
+				"expected !$OMP, got !$ACC"));
+	  omp_acc_err_loc = gfc_current_locus;
+	  goto not_continuation;
 	}
       else if (!openmp_flag && !openacc_flag)
 	for (i = 0; i < 5; i++)
diff --git a/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-1.f b/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-1.f
new file mode 100644
index 00000000000..2e12f1727e4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-1.f
@@ -0,0 +1,23 @@
+! { dg-additional-options "-fdump-tree-original" }
+
+      ! OMP PARALLEL gets parsed  and is properly handled
+      ! But ACC& gives an error
+      ! [Before: an error is printed but OMP parses 'parallel loop ...']
+      subroutine one
+        implicit none
+        integer i
+!$omp parallel
+!$acc& loop independent  !  { dg-error "Wrong OpenMP continuation at .1.: expected !.OMP, got !.ACC" }
+        do i = 1, 5
+        end do
+!$omp end parallel
+      end
+
+      ! [Before: Bogus 'Wrong OpenMP continuation' as it was read as continuation line!]
+      subroutine two
+!$omp parallel
+!$acc loop independent  !  { dg-error "The !.ACC LOOP directive cannot be specified within a !.OMP PARALLEL region" }
+       do i = 1, 5
+       end do
+!$omp end parallel
+       end
diff --git a/gcc/testsuite/gfortran.dg/goacc/omp-fixed.f b/gcc/testsuite/gfortran.dg/goacc/omp-fixed.f
index 6ce6f73c16b..b1e7affc457 100644
--- a/gcc/testsuite/gfortran.dg/goacc/omp-fixed.f
+++ b/gcc/testsuite/gfortran.dg/goacc/omp-fixed.f
@@ -6,7 +6,7 @@
 
 !$OMP PARALLEL
 !$ACC PARALLEL                                                          &
-!$ACC& COPYIN(ARGC) ! { dg-error "directive cannot be specified within" }
+!$ACC& COPYIN(ARGC)  ! { dg-error "The !.ACC PARALLEL directive cannot be specified within a !.OMP PARALLEL region" }
       IF (ARGC .NE. 0) THEN
          STOP 1
       END IF
@@ -24,9 +24,17 @@
 !$OMP& DO ! { dg-error "Wrong OpenACC continuation" }
       DO I = 1, 10
       ENDDO
+!$ACC END PARALLEL
 
 !$OMP PARALLEL                                                          &
 !$ACC& KERNELS LOOP ! { dg-error "Wrong OpenMP continuation" }
       DO I = 1, 10
       ENDDO
+!$OMP END PARALLEL
+
+!$OMP PARALLEL                                                          &
+!$ACC& LOOP ! { dg-error "Wrong OpenMP continuation" }
+      DO I = 1, 10
+      ENDDO
+!$OMP END PARALLEL
       END SUBROUTINE NI
diff --git a/gcc/testsuite/gfortran.dg/goacc/omp.f95 b/gcc/testsuite/gfortran.dg/goacc/omp.f95
index 8b3b2593217..d8bd886ad9c 100644
--- a/gcc/testsuite/gfortran.dg/goacc/omp.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/omp.f95
@@ -67,8 +67,20 @@ contains
    subroutine nana
      !$acc parallel &
      !$omp do ! { dg-error "Wrong OpenACC continuation" }
+     do i = 1, 5 ! { dg-error "The !.OMP DO directive cannot be specified within a !.ACC PARALLEL region" "" { target *-*-* } .-1 }
+     end do
+     !$acc end parallel
 
      !$omp parallel &
      !$acc kernels loop ! { dg-error "Wrong OpenMP continuation" }
+     do i = 1, 5 ! { dg-error "The !.ACC KERNELS LOOP directive cannot be specified within a !.OMP PARALLEL region" "" { target *-*-* } .-1 }
+     end do
+     !$omp end parallel
+
+     !$omp parallel &
+     !$acc loop ! { dg-error "Wrong OpenMP continuation" }
+     do i = 1, 5 ! { dg-error "The !.ACC LOOP directive cannot be specified within a !.OMP PARALLEL region" "" { target *-*-* } .-1 }
+     end do
+     !$omp end parallel
    end subroutine nana
 end module test

Reply via email to