Tobias Burnus wrote:
the following is now applicable to all languages:

  directive-specifier [[,] clause[ [,] clause] ... ]

including Fortran. Hence, this patch now adds support for it.
...
PS: While being there, I noticed that for C/C++ but not for Fortran

... and I noticed wrongly:

Actually, I just cannot grep – and the 'hint' clause on 'critical'
is actually implemented and it is tested for! (In libgomp/testsuite/
but not in gcc/testsuite; possible the reason for missing it.)

Plus: I managed to forget to include the testcase of this patch
in commit

      r17-4506-gb28a16af7fa7fe
      OpenMP/Fortran: Permit comma between directive and clause

despite being listed in the ChangeLog (as I also manged to trim
the changelog to also not include the testcase).


I have now added critical + hint to this comma testcase – and
committed it as r17-4610-gd5f892fb06695a

Sorry,

Tobias
commit d5f892fb06695ad740c6bdeef14e9b5ae6dc74bc
Author: Tobias Burnus <[email protected]>
Date:   Wed Sep 23 14:02:22 2026 +0200

    OpenMP/Fortran: Add gfortran.dg/gomp/directive-comma-clause.f90
    
    Add missing testcase for commit
    
      r17-4506-gb28a16af7fa7fe
      OpenMP/Fortran: Permit comma between directive and clause
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/gomp/directive-comma-clause.f90: New test.

diff --git a/gcc/testsuite/gfortran.dg/gomp/directive-comma-clause.f90 b/gcc/testsuite/gfortran.dg/gomp/directive-comma-clause.f90
new file mode 100644
index 00000000000..bd25362ce8d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/directive-comma-clause.f90
@@ -0,0 +1,201 @@
+! Check for comma between directive and first clause
+! Additionally, check that no space is requires between directive(...)
+! and the first clause
+
+module my_omp_lib_kinds
+        integer, parameter :: omp_lock_hint_kind = 4
+        integer (omp_lock_hint_kind), &
+                 parameter :: omp_sync_hint_none = 0
+        integer (omp_lock_hint_kind), &
+                 parameter :: omp_sync_hint_uncontended = 1
+        integer (omp_lock_hint_kind), &
+                 parameter :: omp_sync_hint_contended = 2
+        integer (omp_lock_hint_kind), &
+                 parameter :: omp_sync_hint_nonspeculative = 4
+        integer (omp_lock_hint_kind), &
+                 parameter :: omp_sync_hint_speculative = 8
+end module 
+
+module m
+  use iso_c_binding, only: c_size_t
+  use my_omp_lib_kinds
+  implicit none
+
+  ! from omp_lib:
+  integer, parameter :: omp_depend_kind = 2*c_size_t
+
+  !$omp requires,dynamic_allocators
+  !$omp requires , reverse_offload
+
+  !$omp assumes,contains(parallel)
+  !$omp assumes , holds(1 > 0)
+  type t
+    integer :: x
+  end type
+  !$omp declare mapper(t :: v)map(v%x)
+  !$omp declare mapper(other : t :: v),map(v%x)
+  !$omp declare mapper(other2 : t :: v) , map(v%x)
+  !$omp declare_mapper(other3 : t :: v)map(v%x)
+  !$omp declare_mapper(other4 : t :: v),map(v%x)
+  !$omp declare_mapper(other5 : t :: v) , map(v%x)
+
+  !$omp declare reduction(one1 : t : omp_out%x = omp_out%x + omp_in%x)initializer(omp_priv%x = 0)
+  !$omp declare reduction(one2 : t : omp_out%x = omp_out%x + omp_in%x),initializer(omp_priv%x = 0)
+  !$omp declare reduction(one3 : t : omp_out%x = omp_out%x + omp_in%x) , initializer(omp_priv%x = 0)
+  !$omp declare_reduction(one4 : t : omp_out%x = omp_out%x + omp_in%x)initializer(omp_priv%x = 0)
+  !$omp declare_reduction(one5 : t : omp_out%x = omp_out%x + omp_in%x),initializer(omp_priv%x = 0)
+  !$omp declare_reduction(one6 : t : omp_out%x = omp_out%x + omp_in%x) , initializer(omp_priv%x = 0)
+
+interface
+    integer function bar1 (x, y, z)
+      integer, value :: x, y, z
+      !$omp declare simd linear (x : val, step (1))linear (y : step (2))
+    end
+    integer function bar2 (x, y, z)
+      integer, value :: x, y, z
+      !$omp declare simd linear (x : val, step (1)),linear (y : step (2))
+    end
+    integer function bar3 (x, y, z)
+      integer, value :: x, y, z
+      !$omp declare simd linear (x : val, step (1)) , linear (y : step (2))
+    end
+    integer function bar4 (x, y, z)
+      integer, value :: x, y, z
+      !$omp declare_simd linear (x : val, step (1))linear (y : step (2))
+    end
+    integer function bar5 (x, y, z)
+      integer, value :: x, y, z
+      !$omp declare_simd linear (x : val, step (1)),linear (y : step (2))
+    end
+    integer function bar6 (x, y, z)
+      integer, value :: x, y, z
+      !$omp declare_simd linear (x : val, step (1)) , linear (y : step (2))
+    end
+end interface
+
+  integer :: a1,a2,a3,a4
+  !$omp declare target,enter(a1)
+  !$omp declare target , enter (a2)
+  !$omp declare_target,enter(a3)
+  !$omp declare_target , enter( a4 )
+
+contains
+  subroutine sub1; end subroutine
+  subroutine sub2; end subroutine
+  subroutine sub3; end subroutine
+  subroutine sub4; end subroutine
+  subroutine sub5; end subroutine
+  subroutine sub6; end subroutine
+  subroutine sub
+    !$omp declare variant(sub1)match(construct={parallel})
+    !$omp declare variant(sub2),match(construct={target})
+    !$omp declare variant(sub3) , match(construct={teams})
+    !$omp declare_variant(sub4)match(construct={target,teams})
+    !$omp declare_variant(sub5),match(user={condition(huge(a2) > 0)})
+    !$omp declare_variant(sub6) , match(user={condition(kind(a1) < 0)})
+
+    !$omp assume,holds(a1 > 0)
+      !$omp assume , holds(a2 < 0)
+      !$omp end assume
+    !$omp end assume
+
+    !$omp begin metadirective,when(user={condition(a3 > 0)}: parallel)
+      a1 = 0
+    !$omp end metadirective
+    !$omp begin metadirective , when(user={condition(a4 > 0)}: parallel)
+      a2 = 0
+    !$omp end metadirective
+
+    !$omp error,at(execution),message("Hello")
+    !$omp error , at(execution) , message("world")
+
+    !$omp metadirective,when(user={condition(a1 /= a2)}: flush)
+    !$omp metadirective , when(user={condition(a2 /= a3)}: taskwait)
+  end subroutine
+
+  subroutine othersub
+    integer :: i, j
+
+    !$omp simd,private(j)
+      do i = 1,1; j = i; end do
+    !$omp simd , private(j)
+      do i = 1,1; j = i; end do
+
+    !$omp do,private(j)
+      do i = 1,1; j = i; end do
+    !$omp do, private(j)
+      do i = 1,1; j = i; end do
+
+    !$omp do simd,private(j)
+      do i = 1,1; j = i; end do
+    !$omp do simd , private(j)
+      do i = 1,1; j = i; end do
+
+    !$omp target parallel,firstprivate(j)
+      !$omp cancellation point,parallel
+
+      !$omp critical,hint(omp_sync_hint_none)
+      !$omp end critical
+
+      !$omp critical , hint(omp_sync_hint_none)
+      !$omp end critical
+
+      !$omp critical(ABC1),hint(omp_sync_hint_none)
+      !$omp end critical(ABC1)
+
+      !$omp critical ( ABC2 ),hint(omp_sync_hint_none)
+      !$omp end critical ( ABC2 )
+
+      !$omp critical (ABC3) , hint(omp_sync_hint_none)
+      !$omp end critical (ABC3)
+
+      !$omp cancel,parallel
+    !$omp end target parallel,nowait 
+
+    !$omp target parallel , firstprivate(j)
+      !$omp cancellation point , parallel
+      !$omp cancel , parallel
+    !$omp end target parallel , nowait 
+
+    !$omp parallel , firstprivate(j)
+      !$omp cancellation_point , parallel
+      !$omp cancel,parallel
+    !$omp end parallel
+
+    !$omp parallel , firstprivate(j)
+      !$omp cancellation point , parallel
+      !$omp cancel , parallel
+    !$omp end parallel
+
+    !$omp atomic,update
+      a1 = a1 + 1
+    !$omp end atomic
+    !$omp atomic , read
+      j = a1
+    !$omp end atomic
+
+    !$omp single,nowait
+    !$omp end single
+    !$omp single , nowait
+    !$omp end single
+    !$omp single
+
+    !$omp end single,nowait
+    !$omp single
+    !$omp end single , nowait
+  end
+
+  subroutine foo
+    integer, save :: i, j, k
+    !$omp groupprivate(k)device_type(nohost)
+    !$omp groupprivate(i),device_type(nohost)
+    !$omp groupprivate(j) , device_type(nohost)
+  end
+
+  subroutine bar
+    integer(omp_depend_kind) :: obj
+    !$omp depobj(obj),depend(in: a1)
+    !$omp depobj(obj)destroy
+    !$omp depobj(obj) , destroy
+  end
+end module m

Reply via email to