For some reasons, I missed the 'cgroup' modifier to 'dyn_groupprivate'
and hadn't implemented it. This commit now adds parsing support; as there
is only 'cgroup' (contention group, i.e. by-team memory), it is
otherwise ignored as there isn't any memory-access type so far.

Committed as r17-5201-g1f94d02d9870ea.

Tobias
commit 1f94d02d9870ea5f1b511241d4d25bd39d54dcc8
Author: Tobias Burnus <[email protected]>
Date:   Wed Oct 14 16:18:15 2026 +0200

    OpenMP/Fortran: Support 'cgroup' modifier to dyn_groupprivate clause
    
    Commit r16-5633-g26d41e245dbba3 added groupprivate parsing support, but
    missed to parse the access-group modifier (with the only value 'cgroup',
    which is also the default). - This commit adds the parsing support.
    
    gcc/fortran/ChangeLog:
    
            * openmp.cc (gfc_match_omp_clauses): Handle 'cgroup' modifier to
            'dyn_groupprivate'.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/gomp/dyn_groupprivate-1.f90: Add tests related to
            the 'cgroup' modifier.
            * gfortran.dg/gomp/dyn_groupprivate-2.f90: Likewise.
---
 gcc/fortran/openmp.cc                              | 82 +++++++++++++++++++---
 .../gfortran.dg/gomp/dyn_groupprivate-1.f90        | 20 +++++-
 .../gfortran.dg/gomp/dyn_groupprivate-2.f90        | 13 +++-
 3 files changed, 105 insertions(+), 10 deletions(-)

diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index c1fe7e22e43..98adc8e0a84 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -3447,16 +3447,82 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      && gfc_match_dupl_check (!c->dyn_groupprivate,
 				       "dyn_groupprivate", true) == MATCH_YES)
 	    {
-	      if (gfc_match ("fallback ( abort ) : ") == MATCH_YES)
-		c->fallback = OMP_FALLBACK_ABORT;
-	      else if (gfc_match ("fallback ( default_mem ) : ") == MATCH_YES)
-		c->fallback = OMP_FALLBACK_DEFAULT_MEM;
-	      else if (gfc_match ("fallback ( null ) : ") == MATCH_YES)
-		c->fallback = OMP_FALLBACK_NULL;
+	      bool cgroup = false;
+	      bool first = true;
+	      bool error_p = false;
+	      do
+		{
+		  old_loc = gfc_current_locus;
+		  if (gfc_match ("cgroup ") == MATCH_YES)
+		    {
+		      if (cgroup)
+			{
+			  gfc_error ("Duplicated %<cgroup%> modifier at %L",
+				     &old_loc);
+			  goto error;
+			}
+		      cgroup = true;
+		    }
+		  else if (gfc_match ("fallback ( ") == MATCH_YES)
+		    {
+		      if (c->fallback != OMP_FALLBACK_NONE)
+			{
+			  gfc_error ("Duplicated %<fallback%> modifier at %L",
+				     &old_loc);
+			  goto error;
+			}
+		      old_loc = gfc_current_locus;
+		      if (gfc_match ("abort ) ") == MATCH_YES)
+			c->fallback = OMP_FALLBACK_ABORT;
+		      else if (gfc_match ("default_mem ) ") == MATCH_YES)
+			c->fallback = OMP_FALLBACK_DEFAULT_MEM;
+		      else if (gfc_match ("null ) ") == MATCH_YES)
+			c->fallback = OMP_FALLBACK_NULL;
+		      else
+			{
+			  gfc_error ("Expected %<abort%>, %<default_mem%> or "
+				     "%<null%> followed by %<)%> at %L",
+				     &old_loc);
+			  goto error;
+			}
+		    }
+		  else if (!first)
+		    {
+		      gfc_error ("Expected %<cgroup%> or %<fallback%> clause at %C");
+		      goto error;
+		    }
+		  if (gfc_match (", ") == MATCH_YES)
+		    {
+		      first = false;
+		      continue;
+		    }
+		  if (gfc_match (": ") == MATCH_YES)
+		    {
+		      old_loc = gfc_current_locus;
+		      break;
+		    }
+		  if (!first)
+		    {
+		      gfc_error ("Expected %<:%> at %C");
+		      goto error;
+		    }
+		  error_p = true;
+		  break;
+		}
+	      while (true);
 	      if (gfc_match_expr (&c->dyn_groupprivate) != MATCH_YES)
-		return MATCH_ERROR;
+		{
+		  gfc_error ("Expected numeric expression at %L, optionally preceeded by "
+			     "the %<cgroup%> and %<fallback%> modifier", &old_loc);
+		  goto error;
+		}
+	      if (error_p)
+		c->fallback = OMP_FALLBACK_NONE;
 	      if (gfc_match (" )") != MATCH_YES)
-		goto error;
+		{
+		  gfc_error ("Expected %<)%> at %C");
+		  goto error;
+		}
 	      continue;
 	    }
 	  break;
diff --git a/gcc/testsuite/gfortran.dg/gomp/dyn_groupprivate-1.f90 b/gcc/testsuite/gfortran.dg/gomp/dyn_groupprivate-1.f90
index a3f86150d5e..4a237945396 100644
--- a/gcc/testsuite/gfortran.dg/gomp/dyn_groupprivate-1.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/dyn_groupprivate-1.f90
@@ -3,8 +3,9 @@
 
 implicit none
 
-integer :: N
+integer :: N, M
 N = 1024
+M = 128
 
 !$omp target dyn_groupprivate(1024)  ! { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" }
 !$omp end target
@@ -20,6 +21,19 @@ N = 1024
 
 !$omp target dyn_groupprivate ( fallback ( default_mem ) : N)  ! { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" }
 !$omp end target
+
+!$omp target dyn_groupprivate(cgroup : 4096)  ! { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" }
+!$omp end target
+
+!$omp target dyn_groupprivate ( fallback ( abort ) , cgroup : M)  ! { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" }
+!$omp end target
+
+!$omp target dyn_groupprivate ( cgroup, fallback ( null ) : M)  ! { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" }
+!$omp end target
+
+!$omp target dyn_groupprivate ( fallback ( default_mem ),cgroup : M)  ! { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" }
+!$omp end target
+
 end
 
 ! { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(1024\\)" 1 "original" } }
@@ -27,3 +41,7 @@ end
 ! { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(fallback\\(abort\\):n\\)" 1 "original" } }
 ! { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(fallback\\(null\\):n\\)" 1 "original" } }
 ! { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(fallback\\(default_mem\\):n\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(4096\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(fallback\\(abort\\):m\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(fallback\\(null\\):m\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(fallback\\(default_mem\\):m\\)" 1 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/dyn_groupprivate-2.f90 b/gcc/testsuite/gfortran.dg/gomp/dyn_groupprivate-2.f90
index 8410334f4f5..4756ad66f65 100644
--- a/gcc/testsuite/gfortran.dg/gomp/dyn_groupprivate-2.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/dyn_groupprivate-2.f90
@@ -19,7 +19,7 @@ block; end block
 !$omp target dyn_groupprivate (0 * M-1)  ! { dg-warning "INTEGER expression of DYN_GROUPPRIVATE clause at .1. must be non-negative \\\[-Wopenmp\\\]" }
 block; end block
 
-!$omp target dyn_groupprivate ( fallback ( other ) : N)  ! { dg-error "Failed to match clause" }
+!$omp target dyn_groupprivate ( fallback ( other ) : N)  ! { dg-error "Expected 'abort', 'default_mem' or 'null' followed by '\\)' at .1." }
 block; end block
 
 !$omp target dyn_groupprivate ( A )  ! { dg-error "DYN_GROUPPRIVATE clause at .1. requires a scalar INTEGER expression" }
@@ -28,4 +28,15 @@ block; end block
 !$omp target dyn_groupprivate ( 1024. )  ! { dg-error "DYN_GROUPPRIVATE clause at .1. requires a scalar INTEGER expression" }
 block; end block
 
+!$omp target dyn_groupprivate ( fallback(null) cgroup: 1024. )  ! { dg-error "Expected '\\)' at .1." }
+block; end block
+
+!$omp target dyn_groupprivate ( fallback(default_mem),thread: 1024. )  ! { dg-error "Expected 'cgroup' or 'fallback' clause at .1." }
+block; end block
+
+!$omp target dyn_groupprivate ( cgroup,fallback(null),cgroup: 1024. )  ! { dg-error "Duplicated 'cgroup' modifier at .1." }
+block; end block
+
+!$omp target dyn_groupprivate ( fallback(abort),cgroup, fallback(abort): 1024. )  ! { dg-error "Duplicated 'fallback' modifier at .1." }
+block; end block
 end

Reply via email to