Trivial patch to permit:
  uses_allocators( traits(t1): alloc1 ; traits(t2): alloc2 )
using ';' to split the items. (With commas, the modifier applies
to all list items; with semicolons, new modifiers can be specified.)

This syntax saves typing of multiple (here: one) ') uses_allocators('
in addition.

Committed as Rev. r16-6273-g7044071f07d763.

Tobias
commit 7044071f07d763444247e32f9db25d7a658b7f9e
Author: Tobias Burnus <[email protected]>
Date:   Fri Dec 19 12:07:58 2025 +0100

    OpenMP: uses_allocators with ';'-separated list
    
    OpenMP 6.0 has the following wording for the uses_allocators clause:
    "More than one clause-argument-specification may be specified";
    this permits ';' lists. While that's pointless for predefined
    allocators, for user-defined allocators it saves redundant
    ') uses_allocators(' by permitting:
      uses_allocators( traits(t1): alloc1 ; traits(t2): alloc2 )
    
    Additionally, the order in the tree dump has been changed to
    place the modifiers before the allocator variable, matching
    the input syntax.
    
    gcc/c/ChangeLog:
    
            * c-parser.cc (c_parser_omp_clause_uses_allocators): Accept
            multiple clause-argument-specifications separated by ';'.
    
    gcc/cp/ChangeLog:
    
            * parser.cc (cp_parser_omp_clause_uses_allocators): Accept
            multiple clause-argument-specifications separated by ';'.
    
    gcc/fortran/ChangeLog:
    
            * openmp.cc (gfc_match_omp_clause_uses_allocators): Accept
            multiple clause-argument-specifications separated by ';'.
    
    gcc/ChangeLog:
    
            * tree-pretty-print.cc (dump_omp_clause): For uses_allocators,
            print modifier before allocator variable.
    
    libgomp/ChangeLog:
    
            * testsuite/libgomp.fortran/uses_allocators-7.f90: Add ';' test.
    
    gcc/testsuite/ChangeLog:
    
            * c-c++-common/gomp/uses_allocators-8.c: New test.

diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index e39429afbb5..8065d3000e6 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -19577,11 +19577,16 @@ c_parser_omp_clause_allocate (c_parser *parser, tree list)
    allocator ( traits-array )
    allocator ( traits-array ) , allocator-list
 
+   Deprecated in 5.2, removed in 6.0: 'allocator(trait-array)' syntax.
+
    OpenMP 5.2:
 
    uses_allocators ( modifier : allocator-list )
    uses_allocators ( modifier , modifier : allocator-list )
 
+   OpenMP 6.0:
+   uses_allocators ( [modifier-list :] allocator-list [; ...] )
+
    modifier:
    traits ( traits-array )
    memspace ( mem-space-handle )  */
@@ -19595,6 +19600,8 @@ c_parser_omp_clause_uses_allocators (c_parser *parser, tree list)
   if (!parens.require_open (parser))
     return list;
 
+parse_next:
+
   bool has_modifiers = false;
   bool seen_allocators = false;
   tree memspace_expr = NULL_TREE;
@@ -19790,6 +19797,12 @@ c_parser_omp_clause_uses_allocators (c_parser *parser, tree list)
 	break;
     }
 
+  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
+    {
+      c_parser_consume_token (parser);
+      goto parse_next;
+    }
+
  end:
   parens.skip_until_found_close (parser);
   return nl;
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index e106583c4b8..4685a9ab80f 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -42815,11 +42815,16 @@ cp_parser_omp_clause_allocate (cp_parser *parser, tree list)
    allocator ( traits-array )
    allocator ( traits-array ) , allocator-list
 
+   Deprecated in 5.2, removed in 6.0: 'allocator(trait-array)' syntax.
+
    OpenMP 5.2:
 
    uses_allocators ( modifier : allocator-list )
    uses_allocators ( modifier , modifier : allocator-list )
 
+   OpenMP 6.0:
+   uses_allocators ( [modifier-list :] allocator-list [; ...] )
+
    modifier:
    traits ( traits-array )
    memspace ( mem-space-handle )  */
@@ -42834,6 +42839,8 @@ cp_parser_omp_clause_uses_allocators (cp_parser *parser, tree list)
   if (!parens.require_open (parser))
     return list;
 
+parse_next:
+
   bool has_modifiers = false;
   bool seen_allocators = false;
   tree memspace_expr = NULL_TREE;
@@ -42988,9 +42995,16 @@ cp_parser_omp_clause_uses_allocators (cp_parser *parser, tree list)
 	break;
     }
 
+  if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+    {
+      cp_lexer_consume_token (parser->lexer);
+      goto parse_next;
+    }
+
   if (!parens.require_close (parser))
     goto end;
   return nl;
+
  end:
   cp_parser_skip_to_closing_parenthesis (parser,
 					 /*recovering=*/true,
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index a7a76694c2c..76c601952a7 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -1795,9 +1795,14 @@ omp_verify_merge_absent_contains (gfc_statement st, gfc_omp_assumptions *check,
      predefined-allocator
      variable ( traits-array )
 
+   OpenMP 5.2 deprecated, 6.0 deleted: 'variable ( traits-array )'
+
    OpenMP 5.2:
    uses_allocators ( [modifier-list :] allocator-list )
 
+   OpenMP 6.0:
+   uses_allocators ( [modifier-list :] allocator-list [; ...])
+
    allocator:
      variable or predefined-allocator
    modifier:
@@ -1807,6 +1812,7 @@ omp_verify_merge_absent_contains (gfc_statement st, gfc_omp_assumptions *check,
 static match
 gfc_match_omp_clause_uses_allocators (gfc_omp_clauses *c)
 {
+parse_next:
   gfc_symbol *memspace_sym = NULL;
   gfc_symbol *traits_sym = NULL;
   gfc_omp_namelist *head = NULL;
@@ -1878,11 +1884,17 @@ gfc_match_omp_clause_uses_allocators (gfc_omp_clauses *c)
 	  p->u.memspace_sym = memspace_sym;
 	  p->u2.traits_sym = traits_sym;
 	}
-      if (gfc_match (", ") == MATCH_YES)
-	continue;
-      if (gfc_match (") ") == MATCH_YES)
+      gfc_gobble_whitespace ();
+      const char c = gfc_peek_ascii_char ();
+      if (c == ';' || c == ')')
 	break;
-      goto error;
+      if (c != ',')
+	{
+	  gfc_error ("Expected %<,%>, %<)%> or %<;%> at %C");
+	  goto error;
+	}
+      gfc_match_char (',');
+      gfc_gobble_whitespace ();
     } while (true);
 
   list = &c->lists[OMP_LIST_USES_ALLOCATORS];
@@ -1890,6 +1902,10 @@ gfc_match_omp_clause_uses_allocators (gfc_omp_clauses *c)
     list = &(*list)->next;
   *list = head;
 
+  if (gfc_match_char (';') == MATCH_YES)
+    goto parse_next;
+
+  gfc_match_char (')');
   return MATCH_YES;
 
 error:
diff --git a/gcc/testsuite/c-c++-common/gomp/uses_allocators-8.c b/gcc/testsuite/c-c++-common/gomp/uses_allocators-8.c
new file mode 100644
index 00000000000..642b6b9caeb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/uses_allocators-8.c
@@ -0,0 +1,59 @@
+// { dg-do compile }
+
+//#include <omp.h>
+
+typedef __UINTPTR_TYPE__ omp_uintptr_t;
+
+#if __cplusplus >= 201103L
+# define __GOMP_UINTPTR_T_ENUM : omp_uintptr_t
+#else
+# define __GOMP_UINTPTR_T_ENUM
+#endif
+
+typedef enum omp_memspace_handle_t __GOMP_UINTPTR_T_ENUM
+{
+  omp_default_mem_space = 0,
+  omp_large_cap_mem_space = 1,
+  omp_const_mem_space = 2,
+  omp_high_bw_mem_space = 3,
+  omp_low_lat_mem_space = 4,
+  ompx_gnu_managed_mem_space = 200,
+  __omp_memspace_handle_t_max__ = __UINTPTR_MAX__
+} omp_memspace_handle_t;
+
+typedef enum omp_allocator_handle_t __GOMP_UINTPTR_T_ENUM
+{
+  omp_null_allocator = 0,
+  omp_default_mem_alloc = 1,
+  omp_large_cap_mem_alloc = 2,
+  omp_const_mem_alloc = 3,
+  omp_high_bw_mem_alloc = 4,
+  omp_low_lat_mem_alloc = 5,
+  omp_cgroup_mem_alloc = 6,
+  omp_pteam_mem_alloc = 7,
+  omp_thread_mem_alloc = 8,
+  ompx_gnu_pinned_mem_alloc = 200,
+  ompx_gnu_managed_mem_alloc = 201,
+  __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+typedef struct omp_alloctrait_t
+{
+//  omp_alloctrait_key_t key;
+//  omp_uintptr_t value;
+} omp_alloctrait_t;
+
+
+void f()
+{
+ omp_allocator_handle_t my, my2, my3, my4;
+const omp_alloctrait_t t[] = {};
+const omp_alloctrait_t t2[] = {};
+ #pragma omp target uses_allocators(traits(t), memspace(omp_high_bw_mem_space) : my; omp_default_mem_alloc, omp_null_allocator; my2; traits(t2) : my3; memspace(omp_large_cap_mem_space) : my4)
+   ;
+}
+
+// { dg-final { scan-tree-dump "#pragma omp target uses_allocators\\(memspace\\(1\\), traits\\(\\) : my4\\) uses_allocators\\(memspace\\(\\), traits\\(t2\\) : my3\\) uses_allocators\\(memspace\\(\\), traits\\(\\) : my2\\) uses_allocators\\(memspace\\(3\\), traits\\(t\\) : my\\)" "original" } }
+
+
+// { dg-message "sorry, unimplemented: 'uses_allocators' clause" "" { target *-*-* } 52 }
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index 15e7ead32e1..54bf7980092 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -908,16 +908,15 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
       break;
 
     case OMP_CLAUSE_USES_ALLOCATORS:
-      pp_string (pp, "uses_allocators(");
-      dump_generic_node (pp, OMP_CLAUSE_USES_ALLOCATORS_ALLOCATOR (clause),
-			 spc, flags, false);
-      pp_string (pp, ": memspace(");
+      pp_string (pp, "uses_allocators(memspace(");
       dump_generic_node (pp, OMP_CLAUSE_USES_ALLOCATORS_MEMSPACE (clause),
 			 spc, flags, false);
       pp_string (pp, "), traits(");
       dump_generic_node (pp, OMP_CLAUSE_USES_ALLOCATORS_TRAITS (clause),
 			 spc, flags, false);
-      pp_right_paren (pp);
+      pp_string (pp, ") : ");
+      dump_generic_node (pp, OMP_CLAUSE_USES_ALLOCATORS_ALLOCATOR (clause),
+			 spc, flags, false);
       pp_right_paren (pp);
       break;
 
diff --git a/libgomp/testsuite/libgomp.fortran/uses_allocators-7.f90 b/libgomp/testsuite/libgomp.fortran/uses_allocators-7.f90
index e5376e46666..32a901a8e02 100644
--- a/libgomp/testsuite/libgomp.fortran/uses_allocators-7.f90
+++ b/libgomp/testsuite/libgomp.fortran/uses_allocators-7.f90
@@ -6,8 +6,15 @@ program main
   implicit none (type, external)
   integer :: x, xbuf(10)
   integer(c_intptr_t) :: iptr
-  integer(omp_allocator_handle_kind) :: my_alloc
+  integer(omp_allocator_handle_kind) :: my_alloc, my, my2, my3, my4
   type(omp_alloctrait), parameter :: trait(*) = [omp_alloctrait(omp_atk_alignment, 128)]
+  type(omp_alloctrait), parameter :: t(*) = [omp_alloctrait:: ]
+  type(omp_alloctrait), parameter :: t2(*) = [omp_alloctrait:: ]
+
+  ! FIXME - improve check that that ';' is handled
+  !$omp target uses_allocators(traits(t), memspace(omp_high_bw_mem_space) : my; omp_default_mem_alloc, omp_null_allocator; my2; traits(t2) : my3; memspace(omp_large_cap_mem_space) : my4)
+  block
+  end block
 
   !$omp target uses_allocators(omp_low_lat_mem_alloc) map(tofrom: x, xbuf) defaultmap(none)
     !$omp parallel allocate(allocator(omp_low_lat_mem_alloc), align(128): x, xbuf) if(.false.) firstprivate(x, xbuf)
@@ -50,9 +57,12 @@ end
 ! FIXME ENABLE: 'dg FIXME final' -> 'dg-final'
 ! { dg  FIXME  final { scan-tree-dump-times "#pragma omp target .*private\\(my_alloc\\).*uses_allocators\\(my_alloc: memspace\\(\\), traits\\(trait\\)\\)" 1 "gimple" } }
 ! { dg  FIXME  final { scan-tree-dump-times "#pragma omp target .*private\\(my_alloc\\).*uses_allocators\\(my_alloc: memspace\\(\\), traits\\(\\)\\)" 1 "gimple" } }
+! { dg  FIXME  final { scan-tree-dump "#pragma omp target uses_allocators\\(memspace\\(1\\), traits\\(\\) : my4\\) uses_allocators\\(memspace\\(\\), traits\\(t2\\) : my3\\) uses_allocators\\(memspace\\(\\), traits\\(\\) : my2\\) uses_allocators\\(memspace\\(3\\), traits\\(t\\) : my\\)" 1 "original" } }
+
 
 ! FIXME ENABLE code above for "gimple" once it has been implemented:
-! { dg-message "sorry, unimplemented: 'uses_allocators' clause with traits and memory spaces" "" { target *-*-* } 23 }
-! { dg-message "sorry, unimplemented: 'uses_allocators' clause with traits and memory spaces" "" { target *-*-* } 36 }
-! { dg-bogus "'my_alloc' not specified in enclosing 'target'" "bogus issue because clause is ignored" { xfail *-*-* } 24 }
-! { dg-bogus "'my_alloc' not specified in enclosing 'target'" "bogus issue because clause is ignored" { xfail *-*-* } 37 }
+! { dg-message "sorry, unimplemented: 'uses_allocators' clause with traits and memory spaces" "" { target *-*-* } 15 }
+! { dg-message "sorry, unimplemented: 'uses_allocators' clause with traits and memory spaces" "" { target *-*-* } 30 }
+! { dg-message "sorry, unimplemented: 'uses_allocators' clause with traits and memory spaces" "" { target *-*-* } 43 }
+! { dg-bogus "'my_alloc' not specified in enclosing 'target'" "bogus issue because clause is ignored" { xfail *-*-* } 31 }
+! { dg-bogus "'my_alloc' not specified in enclosing 'target'" "bogus issue because clause is ignored" { xfail *-*-* } 44 }

Reply via email to