public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
From: Tobias Burnus <tobias@codesourcery.com>
To: gcc-patches <gcc-patches@gcc.gnu.org>,
	Jakub Jelinek <jakub@redhat.com>, fortran <fortran@gcc.gnu.org>
Subject: [Patch] OpenMP/Fortran: Permit end-clause on directive
Date: Fri, 26 Aug 2022 20:21:26 +0200	[thread overview]
Message-ID: <821786f3-ac7b-01e3-a386-f7c082494022@codesourcery.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 658 bytes --]

I did run into some issues related to this; those turned out to be
unrelated, but I end ended up implementing this feature.

Side remark: 'omp parallel workshare' seems to actually permit 'nowait'
now, but I guess that's an unintended change due to the
syntax-representation change. Hence, it is now tracked as Spec Issue
3338 and I do not permit it.

OK for mainline?

Tobias
-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

[-- Attachment #2: end-decl.diff --]
[-- Type: text/x-patch, Size: 28465 bytes --]

OpenMP/Fortran: Permit end-clause on directive

gcc/fortran/ChangeLog:

	* openmp.cc (OMP_DO_CLAUSES, OMP_SCOPE_CLAUSES,
	OMP_SECTIONS_CLAUSES, OMP_SINGLE_CLAUSES): Add 'nowait'.
	(gfc_match_omp_distribute_parallel_do,
	gfc_match_omp_distribute_parallel_do_simd,
	gfc_match_omp_parallel_do,
	gfc_match_omp_parallel_do_simd,
	gfc_match_omp_parallel_sections,
	gfc_match_omp_teams_distribute_parallel_do,
	gfc_match_omp_teams_distribute_parallel_do_simd): Disallow 'nowait'.
	gfc_match_omp_workshare): Match 'nowait' clause.
	(gfc_match_omp_end_single): Use clause matcher for 'nowait'.
	(resolve_omp_clauses): Reject 'nowait' + 'copyprivate'.
	* parse.cc (decode_omp_directive): Break too long line.
	(parse_omp_do, parse_omp_structured_block): Diagnose duplicated
	'nowait' clause.

libgomp/ChangeLog:

	* libgomp.texi (OpenMP 5.2): Mark end-directive as Y.

gcc/testsuite/ChangeLog:

	* gfortran.dg/gomp/copyprivate-1.f90: New test.
	* gfortran.dg/gomp/copyprivate-2.f90: New test.
	* gfortran.dg/gomp/nowait-4.f90: New test.
	* gfortran.dg/gomp/nowait-5.f90: New test.
	* gfortran.dg/gomp/nowait-6.f90: New test.

 gcc/fortran/openmp.cc                            |  55 ++--
 gcc/fortran/parse.cc                             |  33 ++-
 gcc/testsuite/gfortran.dg/gomp/copyprivate-1.f90 |  21 ++
 gcc/testsuite/gfortran.dg/gomp/copyprivate-2.f90 |  69 +++++
 gcc/testsuite/gfortran.dg/gomp/nowait-4.f90      | 315 +++++++++++++++++++++++
 gcc/testsuite/gfortran.dg/gomp/nowait-5.f90      | 118 +++++++++
 gcc/testsuite/gfortran.dg/gomp/nowait-6.f90      |  92 +++++++
 libgomp/libgomp.texi                             |   2 +-
 8 files changed, 673 insertions(+), 32 deletions(-)

diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 594907714ff..b3b6fc17828 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -3795,17 +3795,19 @@ cleanup:
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
    | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION			\
    | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE	\
-   | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER | OMP_CLAUSE_ALLOCATE)
+   | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER | OMP_CLAUSE_ALLOCATE		\
+   | OMP_CLAUSE_NOWAIT)
 #define OMP_LOOP_CLAUSES \
   (omp_mask (OMP_CLAUSE_BIND) | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_ORDER	\
    | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
 
 #define OMP_SCOPE_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) |OMP_CLAUSE_FIRSTPRIVATE		\
-   | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE)
+   | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
 #define OMP_SECTIONS_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
-   | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE)
+   | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION			\
+   | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
 #define OMP_SIMD_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE		\
    | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN	\
@@ -3855,7 +3857,7 @@ cleanup:
    | OMP_CLAUSE_ORDER | OMP_CLAUSE_ALLOCATE)
 #define OMP_SINGLE_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
-   | OMP_CLAUSE_ALLOCATE)
+   | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_COPYPRIVATE)
 #define OMP_ORDERED_CLAUSES \
   (omp_mask (OMP_CLAUSE_THREADS) | OMP_CLAUSE_SIMD)
 #define OMP_DECLARE_TARGET_CLAUSES \
@@ -4020,8 +4022,8 @@ gfc_match_omp_distribute_parallel_do (void)
   return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO,
 		    (OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES
 		     | OMP_DO_CLAUSES)
-		    & ~(omp_mask (OMP_CLAUSE_ORDERED))
-		    & ~(omp_mask (OMP_CLAUSE_LINEAR)));
+		    & ~(omp_mask (OMP_CLAUSE_ORDERED)
+			| OMP_CLAUSE_LINEAR | OMP_CLAUSE_NOWAIT));
 }
 
 
@@ -4031,7 +4033,7 @@ gfc_match_omp_distribute_parallel_do_simd (void)
   return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD,
 		    (OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES
 		     | OMP_DO_CLAUSES | OMP_SIMD_CLAUSES)
-		    & ~(omp_mask (OMP_CLAUSE_ORDERED)));
+		    & ~(omp_mask (OMP_CLAUSE_ORDERED) | OMP_CLAUSE_NOWAIT));
 }
 
 
@@ -5332,7 +5334,8 @@ match
 gfc_match_omp_parallel_do (void)
 {
   return match_omp (EXEC_OMP_PARALLEL_DO,
-		    OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES);
+		    (OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES)
+		    & ~(omp_mask (OMP_CLAUSE_NOWAIT)));
 }
 
 
@@ -5340,7 +5343,8 @@ match
 gfc_match_omp_parallel_do_simd (void)
 {
   return match_omp (EXEC_OMP_PARALLEL_DO_SIMD,
-		    OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES | OMP_SIMD_CLAUSES);
+		    (OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES | OMP_SIMD_CLAUSES)
+		    & ~(omp_mask (OMP_CLAUSE_NOWAIT)));
 }
 
 
@@ -5396,7 +5400,8 @@ match
 gfc_match_omp_parallel_sections (void)
 {
   return match_omp (EXEC_OMP_PARALLEL_SECTIONS,
-		    OMP_PARALLEL_CLAUSES | OMP_SECTIONS_CLAUSES);
+		    (OMP_PARALLEL_CLAUSES | OMP_SECTIONS_CLAUSES)
+		    & ~(omp_mask (OMP_CLAUSE_NOWAIT)));
 }
 
 
@@ -5882,8 +5887,8 @@ gfc_match_omp_teams_distribute_parallel_do (void)
   return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO,
 		    (OMP_TEAMS_CLAUSES | OMP_DISTRIBUTE_CLAUSES
 		     | OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES)
-		    & ~(omp_mask (OMP_CLAUSE_ORDERED))
-		    & ~(omp_mask (OMP_CLAUSE_LINEAR)));
+		    & ~(omp_mask (OMP_CLAUSE_ORDERED)
+			| OMP_CLAUSE_LINEAR | OMP_CLAUSE_NOWAIT));
 }
 
 
@@ -5893,7 +5898,8 @@ gfc_match_omp_teams_distribute_parallel_do_simd (void)
   return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
 		    (OMP_TEAMS_CLAUSES | OMP_DISTRIBUTE_CLAUSES
 		     | OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES
-		     | OMP_SIMD_CLAUSES) & ~(omp_mask (OMP_CLAUSE_ORDERED)));
+		     | OMP_SIMD_CLAUSES)
+		    & ~(omp_mask (OMP_CLAUSE_ORDERED) | OMP_CLAUSE_NOWAIT));
 }
 
 
@@ -5909,13 +5915,11 @@ gfc_match_omp_teams_distribute_simd (void)
 match
 gfc_match_omp_workshare (void)
 {
-  if (gfc_match_omp_eos () != MATCH_YES)
-    {
-      gfc_error ("Unexpected junk after $OMP WORKSHARE statement at %C");
-      return MATCH_ERROR;
-    }
+  gfc_omp_clauses *c;
+  if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_NOWAIT)) != MATCH_YES)
+    return MATCH_ERROR;
   new_st.op = EXEC_OMP_WORKSHARE;
-  new_st.ext.omp_clauses = gfc_get_omp_clauses ();
+  new_st.ext.omp_clauses = c;
   return MATCH_YES;
 }
 
@@ -6220,14 +6224,8 @@ match
 gfc_match_omp_end_single (void)
 {
   gfc_omp_clauses *c;
-  if (gfc_match ("% nowait") == MATCH_YES)
-    {
-      new_st.op = EXEC_OMP_END_NOWAIT;
-      new_st.ext.omp_bool = true;
-      return MATCH_YES;
-    }
-  if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_COPYPRIVATE))
-      != MATCH_YES)
+  if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_COPYPRIVATE)
+					   | OMP_CLAUSE_NOWAIT) != MATCH_YES)
     return MATCH_ERROR;
   new_st.op = EXEC_OMP_END_SINGLE;
   new_st.ext.omp_clauses = c;
@@ -6954,6 +6952,9 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 	      }
 	    break;
 	  case OMP_LIST_COPYPRIVATE:
+	    if (omp_clauses->nowait)
+	      gfc_error ("NOWAIT clause must not be be used with COPYPRIVATE "
+			 "clause at %L", &n->where);
 	    for (; n != NULL; n = n->next)
 	      {
 		if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc
index 80492c952aa..8a1bfda64d6 100644
--- a/gcc/fortran/parse.cc
+++ b/gcc/fortran/parse.cc
@@ -939,7 +939,8 @@ decode_omp_directive (void)
       matchs ("end ordered", gfc_match_omp_eos_error, ST_OMP_END_ORDERED);
       matchs ("end parallel do simd", gfc_match_omp_eos_error,
 	      ST_OMP_END_PARALLEL_DO_SIMD);
-      matcho ("end parallel do", gfc_match_omp_eos_error, ST_OMP_END_PARALLEL_DO);
+      matcho ("end parallel do", gfc_match_omp_eos_error,
+	      ST_OMP_END_PARALLEL_DO);
       matcho ("end parallel loop", gfc_match_omp_eos_error,
 	      ST_OMP_END_PARALLEL_LOOP);
       matcho ("end parallel masked taskloop simd", gfc_match_omp_eos_error,
@@ -5284,7 +5285,13 @@ parse_omp_do (gfc_statement omp_st)
   if (st == omp_end_st)
     {
       if (new_st.op == EXEC_OMP_END_NOWAIT)
-	cp->ext.omp_clauses->nowait |= new_st.ext.omp_bool;
+	{
+	  if (cp->ext.omp_clauses->nowait && new_st.ext.omp_bool)
+	    gfc_error_now ("Duplicated NOWAIT clause on %s and %s at %C",
+			   gfc_ascii_statement (omp_st),
+			   gfc_ascii_statement (omp_end_st));
+	  cp->ext.omp_clauses->nowait |= new_st.ext.omp_bool;
+	}
       else
 	gcc_assert (new_st.op == EXEC_NOP);
       gfc_clear_new_st ();
@@ -5720,6 +5727,10 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only)
   switch (new_st.op)
     {
     case EXEC_OMP_END_NOWAIT:
+      if (cp->ext.omp_clauses->nowait && new_st.ext.omp_bool)
+	gfc_error_now ("Duplicated NOWAIT clause on %s and %s at %C",
+		       gfc_ascii_statement (omp_st),
+		       gfc_ascii_statement (omp_end_st));
       cp->ext.omp_clauses->nowait |= new_st.ext.omp_bool;
       break;
     case EXEC_OMP_END_CRITICAL:
@@ -5734,8 +5745,22 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only)
       new_st.ext.omp_name = NULL;
       break;
     case EXEC_OMP_END_SINGLE:
-      cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE]
-	= new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE];
+      if (cp->ext.omp_clauses->nowait && new_st.ext.omp_clauses->nowait)
+	gfc_error_now ("Duplicated NOWAIT clause on %s and %s at %C",
+		       gfc_ascii_statement (omp_st),
+		       gfc_ascii_statement (omp_end_st));
+      cp->ext.omp_clauses->nowait |= new_st.ext.omp_clauses->nowait;
+      if (cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE])
+	{
+	  gfc_omp_namelist *nl;
+	  for (nl = cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE];
+	      nl->next; nl = nl->next);
+	    ;
+	  nl->next = new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE];
+	}
+      else
+	cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE]
+	  = new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE];
       new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE] = NULL;
       gfc_free_omp_clauses (new_st.ext.omp_clauses);
       break;
diff --git a/gcc/testsuite/gfortran.dg/gomp/copyprivate-1.f90 b/gcc/testsuite/gfortran.dg/gomp/copyprivate-1.f90
new file mode 100644
index 00000000000..eb2c865818e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/copyprivate-1.f90
@@ -0,0 +1,21 @@
+! based on pr59467.f90 but COPYPRIVATE on the directive
+! { dg-additional-options "-fdump-tree-original" }
+
+  FUNCTION t()
+    INTEGER :: a, b, t
+    a = 0
+    b = 0
+    t = b
+    b = 0
+    !$OMP PARALLEL REDUCTION(+:b)
+      !$OMP SINGLE COPYPRIVATE (b)
+        !$OMP ATOMIC WRITE
+        b = 6
+      !$OMP END SINGLE
+    !$OMP END PARALLEL
+    t = t + b
+  END FUNCTION
+
+! { dg-final { scan-tree-dump-times "#pragma omp parallel reduction\\(\\+:b\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp single copyprivate\\(b\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp atomic relaxed" 1 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/copyprivate-2.f90 b/gcc/testsuite/gfortran.dg/gomp/copyprivate-2.f90
new file mode 100644
index 00000000000..6615ed8688a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/copyprivate-2.f90
@@ -0,0 +1,69 @@
+  FUNCTION t()
+    INTEGER :: a, b, t
+    a = 0
+    t = b
+    b = 0
+    !$OMP PARALLEL REDUCTION(+:b)
+      !$OMP SINGLE COPYPRIVATE (b) NOWAIT  ! { dg-error "NOWAIT clause must not be be used with COPYPRIVATE clause" }
+        !$OMP ATOMIC WRITE
+        b = 6
+      !$OMP END SINGLE
+    !$OMP END PARALLEL
+    t = t + b
+  END FUNCTION
+
+  FUNCTION t2()
+    INTEGER :: a, b, t2
+    a = 0
+    t2 = b
+    b = 0
+    !$OMP PARALLEL REDUCTION(+:b)
+      !$OMP SINGLE NOWAIT COPYPRIVATE (b)  ! { dg-error "NOWAIT clause must not be be used with COPYPRIVATE clause" }
+        !$OMP ATOMIC WRITE
+        b = 6
+      !$OMP END SINGLE
+    !$OMP END PARALLEL
+    t2 = t2 + b
+  END FUNCTION
+
+  FUNCTION t3()
+    INTEGER :: a, b, t3
+    a = 0
+    t3 = b
+    b = 0
+    !$OMP PARALLEL REDUCTION(+:b)
+      !$OMP SINGLE COPYPRIVATE (b)  ! { dg-error "NOWAIT clause must not be be used with COPYPRIVATE clause" }
+        !$OMP ATOMIC WRITE
+        b = 6
+      !$OMP END SINGLE NOWAIT
+    !$OMP END PARALLEL
+    t3 = t3 + b
+  END FUNCTION
+
+  FUNCTION t4()
+    INTEGER :: a, b, t4
+    a = 0
+    t4 = b
+    b = 0
+    !$OMP PARALLEL REDUCTION(+:b)
+      !$OMP SINGLE
+        !$OMP ATOMIC WRITE
+        b = 6
+      !$OMP END SINGLE NOWAIT COPYPRIVATE (b)  ! { dg-error "NOWAIT clause must not be be used with COPYPRIVATE clause" }
+    !$OMP END PARALLEL
+    t4 = t4 + b
+  END FUNCTION
+
+  FUNCTION t5()
+    INTEGER :: a, b, t5
+    a = 0
+    t5 = b
+    b = 0
+    !$OMP PARALLEL REDUCTION(+:b)
+      !$OMP SINGLE
+        !$OMP ATOMIC WRITE
+        b = 6
+      !$OMP END SINGLE COPYPRIVATE (b) NOWAIT  ! { dg-error "NOWAIT clause must not be be used with COPYPRIVATE clause" }
+    !$OMP END PARALLEL
+    t5 = t5 + b
+  END FUNCTION
diff --git a/gcc/testsuite/gfortran.dg/gomp/nowait-4.f90 b/gcc/testsuite/gfortran.dg/gomp/nowait-4.f90
new file mode 100644
index 00000000000..8472df95f83
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/nowait-4.f90
@@ -0,0 +1,315 @@
+! Cross check that it is accepted without nowait
+subroutine bar()
+implicit none
+integer :: i, a(5)
+!$omp atomic write
+i = 5
+!$omp end atomic
+
+!$omp critical
+!$omp end critical
+
+!$omp distribute
+do i = 1, 5
+end do
+!$omp end distribute
+
+!$omp distribute parallel do
+do i = 1, 5
+end do
+!$omp end distribute parallel do
+
+!$omp distribute parallel do simd
+do i = 1, 5
+end do
+!$omp end distribute parallel do simd
+
+!$omp distribute simd
+do i = 1, 5
+end do
+!$omp end distribute simd
+
+!$omp masked
+!$omp end masked
+
+!$omp masked taskloop
+do i = 1, 5
+end do
+!$omp end masked taskloop
+
+!$omp masked taskloop simd
+do i = 1, 5
+end do
+!$omp end masked taskloop simd
+
+!$omp master
+!$omp end master
+
+!$omp master taskloop
+do i = 1, 5
+end do
+!$omp end master taskloop
+
+!$omp master taskloop simd
+do i = 1, 5
+end do
+!$omp end master taskloop simd
+
+!$omp ordered
+!$omp end ordered
+
+!$omp parallel
+!$omp end parallel
+
+!$omp parallel workshare
+a(:) = 5
+!$omp end parallel workshare
+
+!$omp parallel do
+do i = 1, 5
+end do
+!$omp end parallel do
+
+!$omp parallel do simd
+do i = 1, 5
+end do
+!$omp end parallel do simd
+
+!$omp parallel sections
+  !$omp section
+  block; end block
+!$omp end parallel sections
+
+!$omp parallel masked
+!$omp end parallel masked
+
+!$omp parallel masked taskloop
+do i = 1, 5
+end do
+!$omp end parallel masked taskloop
+
+!$omp parallel masked taskloop simd
+do i = 1, 5
+end do
+!$omp end parallel masked taskloop simd
+
+!$omp parallel master
+!$omp end parallel master
+
+!$omp parallel master taskloop
+do i = 1, 5
+end do
+!$omp end parallel master taskloop
+
+!$omp parallel master taskloop simd
+do i = 1, 5
+end do
+!$omp end parallel master taskloop simd
+
+!$omp simd
+do i = 1, 5
+end do
+!$omp end simd
+
+!$omp task
+!$omp end task
+
+!$omp taskgroup
+!$omp end taskgroup
+
+!$omp taskloop
+do i = 1, 5
+end do
+!$omp end taskloop
+
+!$omp taskloop simd
+do i = 1, 5
+end do
+!$omp end taskloop simd
+
+!$omp teams
+!$omp end teams
+
+!$omp teams distribute
+do i = 1, 5
+end do
+!$omp end teams distribute
+
+!$omp teams distribute parallel do
+do i = 1, 5
+end do
+!$omp end teams distribute parallel do
+
+!$omp teams distribute parallel do simd
+do i = 1, 5
+end do
+!$omp end teams distribute parallel do simd
+
+!$omp teams distribute simd
+do i = 1, 5
+end do
+!$omp end teams distribute simd
+
+!$omp target data map(tofrom:i)
+!$omp end target data
+
+end
+
+! invalid nowait
+
+subroutine foo
+implicit none
+integer :: i, a(5)
+!$omp atomic write nowait  ! { dg-error "Failed to match clause" }
+i = 5
+!$omp end atomic  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp critical nowait  ! { dg-error "Failed to match clause" }
+!$omp end critical  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp distribute nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end distribute  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp distribute parallel do nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end distribute parallel do  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp distribute parallel do simd nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end distribute parallel do simd  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel sections nowait  ! { dg-error "Failed to match clause" }
+  !$omp section  ! { dg-error "Unexpected ..OMP SECTION statement" }
+  block; end block
+!$omp end parallel sections  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp distribute simd nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end distribute simd  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp masked nowait  ! { dg-error "Failed to match clause" }
+!$omp end masked  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp masked taskloop nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end masked taskloop  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp masked taskloop simd nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end masked taskloop simd  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp master nowait  ! { dg-error "Unexpected junk" }
+!$omp end master  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp master taskloop nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end master taskloop  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp master taskloop simd nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end master taskloop simd  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp ordered nowait  ! { dg-error "Failed to match clause" }
+!$omp end ordered  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel nowait  ! { dg-error "Failed to match clause" }
+!$omp end parallel  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel workshare nowait  ! { dg-error "Failed to match clause" }
+a(:) = 5
+!$omp end parallel workshare  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel do nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end parallel do  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel do simd nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end parallel do simd  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel masked nowait  ! { dg-error "Failed to match clause" }
+!$omp end parallel masked  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel masked taskloop nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end parallel masked taskloop  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel masked taskloop simd nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end parallel masked taskloop simd  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel master nowait  ! { dg-error "Failed to match clause" }
+!$omp end parallel master  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel master taskloop nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end parallel master taskloop  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel master taskloop simd nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end parallel master taskloop simd  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp simd nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end simd  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp task nowait  ! { dg-error "Failed to match clause" }
+!$omp end task  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp taskgroup nowait  ! { dg-error "Failed to match clause" }
+!$omp end taskgroup  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp taskloop nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end taskloop  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp taskloop simd nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end taskloop simd  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp teams nowait  ! { dg-error "Failed to match clause" }
+!$omp end teams  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp teams distribute nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end teams distribute  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp teams distribute parallel do nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end teams distribute parallel do  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp teams distribute parallel do simd nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end teams distribute parallel do simd  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp teams distribute simd nowait  ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end teams distribute simd  ! { dg-error "Unexpected ..OMP END " }
+
+!$omp target data map(tofrom:i) nowait  ! { dg-error "Failed to match clause" }
+!$omp end target data  ! { dg-error "Unexpected ..OMP END " }
+
+end
+! { dg-prune-output "Unexpected end of file" }
diff --git a/gcc/testsuite/gfortran.dg/gomp/nowait-5.f90 b/gcc/testsuite/gfortran.dg/gomp/nowait-5.f90
new file mode 100644
index 00000000000..41ead2f7eeb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/nowait-5.f90
@@ -0,0 +1,118 @@
+! { dg-additional-options "-fdump-tree-original" }
+
+subroutine foo
+implicit none
+integer :: i, a(5)
+
+!$omp do nowait
+do i = 1, 5
+end do
+!$omp end do
+
+!$omp do simd nowait
+do i = 1, 5
+end do
+!$omp end do simd
+
+!$omp scope nowait
+!$omp end scope
+
+!$omp sections nowait
+  !$omp section
+  block; end block
+!$omp end sections
+
+!$omp single nowait
+!$omp end single
+
+!$omp target nowait
+!$omp end target
+
+!$omp target parallel nowait
+!$omp end target parallel
+
+!$omp target parallel do nowait
+do i = 1, 5
+end do
+!$omp end target parallel do
+
+!$omp target parallel do simd nowait
+do i = 1, 5
+end do
+!$omp end target parallel do simd
+
+!$omp target parallel loop nowait
+do i = 1, 5
+end do
+!$omp end target parallel loop
+
+!$omp target teams distribute parallel do nowait
+do i = 1, 5
+end do
+!$omp end target teams distribute parallel do
+
+!$omp target teams distribute parallel do simd nowait
+do i = 1, 5
+end do
+!$omp end target teams distribute parallel do simd
+
+!$omp target simd nowait
+do i = 1, 5
+end do
+!$omp end target simd
+
+!$omp target teams nowait
+!$omp end target teams
+
+!$omp target teams distribute nowait
+do i = 1, 5
+end do
+!$omp end target teams distribute
+
+!$omp target teams distribute simd nowait
+do i = 1, 5
+end do
+!$omp end target teams distribute simd
+
+!$omp target teams loop nowait
+do i = 1, 5
+end do
+!$omp end target teams loop
+
+!$omp workshare nowait
+A(:) = 5
+!$omp end workshare
+end
+
+! Note: internally, for '... parallel do ...', 'nowait' is always added
+! such that for 'omp end target parallel do nowait', 'nowait' is on both
+! 'target' as specified in the OpenMP spec and and on 'do' due to internal usage.
+
+! Expected with 'nowait'
+
+! { dg-final { scan-tree-dump-times "#pragma omp for nowait" 6 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp for schedule\\(static\\) nowait" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp sections nowait" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp single nowait" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target nowait" 12 "original" } }
+
+! Never:
+
+! { dg-final { scan-tree-dump-not "#pragma omp distribute\[^\n\r]*nowait" "original" } }
+! { dg-final { scan-tree-dump-not "#pragma omp loop\[^\n\r]*nowait" "original" } }
+! { dg-final { scan-tree-dump-not "#pragma omp parallel\[^\n\r]*nowait" "original" } }
+! { dg-final { scan-tree-dump-not "#pragma omp section\[^s\]\[^\n\r]*nowait" "original" } }
+! { dg-final { scan-tree-dump-not "#pragma omp simd\[^\n\r]*nowait" "original" } }
+! { dg-final { scan-tree-dump-not "#pragma omp teams\[^\n\r]*nowait" "original" } }
+
+! Sometimes or never with nowait:
+
+! { dg-final { scan-tree-dump-times "#pragma omp distribute\[\n\r]" 4 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp loop\[\n\r]" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel\[\n\r]" 6 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp section\[\n\r]" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\)\[\n\r]" 5 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp teams\[\n\r]" 6 "original" } }
+
+! { dg-final { scan-tree-dump-times "#pragma omp target\[\n\r]" 0 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp for\[\n\r]" 0 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/nowait-6.f90 b/gcc/testsuite/gfortran.dg/gomp/nowait-6.f90
new file mode 100644
index 00000000000..5e666d123c5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/nowait-6.f90
@@ -0,0 +1,92 @@
+subroutine foo
+implicit none
+integer :: i, a(5)
+
+!$omp do nowait nowait  ! { dg-error "Duplicated 'nowait' clause" }
+do i = 1, 5
+end do
+
+!$omp do
+do i = 1, 5
+end do
+!$omp do nowait nowait  ! { dg-error "Duplicated 'nowait' clause" }
+
+!$omp do nowait
+do i = 1, 5
+end do
+!$omp end do nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp do simd nowait
+do i = 1, 5
+end do
+!$omp end do simd nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp scope nowait
+!$omp end scope nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp sections nowait
+  !$omp section
+  block; end block
+!$omp end sections nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp single nowait
+!$omp end single nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target nowait
+!$omp end target nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target parallel nowait
+!$omp end target parallel nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target parallel do nowait
+do i = 1, 5
+end do
+!$omp end target parallel do nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target parallel do simd nowait
+do i = 1, 5
+end do
+!$omp end target parallel do simd nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target parallel loop nowait
+do i = 1, 5
+end do
+!$omp end target parallel loop nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target teams distribute parallel do nowait
+do i = 1, 5
+end do
+!$omp end target teams distribute parallel do nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target teams distribute parallel do simd nowait
+do i = 1, 5
+end do
+!$omp end target teams distribute parallel do simd nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target simd nowait
+do i = 1, 5
+end do
+!$omp end target simd nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target teams nowait
+!$omp end target teams nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target teams distribute nowait
+do i = 1, 5
+end do
+!$omp end target teams distribute nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target teams distribute simd nowait
+do i = 1, 5
+end do
+!$omp end target teams distribute simd nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target teams loop nowait
+do i = 1, 5
+end do
+!$omp end target teams loop nowait  ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp workshare nowait
+A(:) = 5
+!$omp end workshare nowait  ! { dg-error "Duplicated NOWAIT clause" }
+end
diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index 0f2998cf8f1..6d580f70b2b 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -360,7 +360,7 @@ to address of matching mapped list item per 5.1, Sect. 2.21.7.2 @tab N @tab
       @tab N @tab
 @item @code{omp}/@code{ompx}/@code{omx} sentinels and @code{omp_}/@code{ompx_}
       namespaces @tab N/A @tab
-@item Clauses on @code{end} directive can be on directive @tab N @tab
+@item Clauses on @code{end} directive can be on directive @tab Y @tab
 @item Deprecation of no-argument @code{destroy} clause on @code{depobj}
       @tab N @tab
 @item @code{linear} clause syntax changes and @code{step} modifier @tab Y @tab

             reply	other threads:[~2022-08-26 18:21 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-26 18:21 Tobias Burnus [this message]
2022-08-29 20:49 ` Harald Anlauf
2022-09-08 15:21 ` Jakub Jelinek
2022-09-08 15:25   ` Jakub Jelinek
2022-11-27 17:38   ` Tobias Burnus

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=821786f3-ac7b-01e3-a386-f7c082494022@codesourcery.com \
    --to=tobias@codesourcery.com \
    --cc=fortran@gcc.gnu.org \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).