https://gcc.gnu.org/g:167ae48aca1d82a2dc3fcab984bd81b0347c92d4

commit 167ae48aca1d82a2dc3fcab984bd81b0347c92d4
Author: Sandra Loosemore <[email protected]>
Date:   Mon Jun 1 20:26:36 2026 +0000

    OpenMP, C++: Diagnose inappropriate allocators for static variables 
[PR122892]
    
    Commit gcc-17-985-g2946b3a7788 added a C and Fortran front-end
    diagnostic for certain allocators for static variables that are
    disallowed in OpenMP 6.1.  This patch adds a similar diagnostic to the
    new C++ front end support and adjusts the test cases to no longer fail.
    
    gcc/cp/ChangeLog
            PR c/122892
            * semantics.cc (finish_omp_allocate): Diagnose invalid allocators.
    
    gcc/testsuite/ChangeLog
            PR c/122892
            * c-c++-common/gomp/allocate-20.c: Remove expected "sorry" for C++,
            and add new dg-error patterns for the C++ error messages.
            * g++.dg/gomp/allocate-handles-2.C: Replace the implicit loop over
            the predefined allocators with explicit calls, since some of them
            are expected to trigger an error and others aren't.

Diff:
---
 gcc/cp/semantics.cc                            | 14 ++++++++++
 gcc/testsuite/c-c++-common/gomp/allocate-20.c  | 31 ++++++---------------
 gcc/testsuite/g++.dg/gomp/allocate-handles-2.C | 37 +++++++++++++-------------
 3 files changed, 40 insertions(+), 42 deletions(-)

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index eef0162a7c14..714dcddaf6f8 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12941,6 +12941,20 @@ finish_omp_allocate (const location_t loc, const tree 
var_list,
                  "expression evaluates to %qwu", tree_to_uhwi (ret));
          return error_mark_node;
        }
+      const bool cgroup_pteam_thread_allocator
+       = (alloc_value == GOMP_OMP_PREDEF_ALLOC_CGROUP
+          || alloc_value == GOMP_OMP_PREDEF_ALLOC_PTEAM
+          || alloc_value == GOMP_OMP_PREDEF_ALLOC_THREAD);
+      if (cgroup_pteam_thread_allocator)
+       {
+         auto_diagnostic_group d;
+         error_at (EXPR_LOCATION (alloc_in),
+                   "%<allocator%> clause must not be "
+                   "%<omp_cgroup_mem_alloc%>, %<omp_pteam_mem_alloc%>, "
+                   "or %<omp_thread_mem_alloc%>");
+         emit_diag_for_static_vars ();
+         return error_mark_node;
+       }
       return ret;
     } (); /* IILE.  */
 
diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-20.c 
b/gcc/testsuite/c-c++-common/gomp/allocate-20.c
index 397d29a3599f..d0a8c0d1a6a7 100644
--- a/gcc/testsuite/c-c++-common/gomp/allocate-20.c
+++ b/gcc/testsuite/c-c++-common/gomp/allocate-20.c
@@ -37,28 +37,20 @@ static int g9;
 static int g10;
 
 #pragma omp allocate(g0) allocator(omp_null_allocator)  // { dg-error 
"'allocator' clause requires a predefined allocator as 'g0' is static" "" { 
target c } }
+// { dg-error "'allocator' clause requires a constant predefined allocator" "" 
{ target c++ } .-1 }
 #pragma omp allocate(g1) allocator(omp_default_mem_alloc)
 #pragma omp allocate(g2) allocator(omp_large_cap_mem_alloc)
 #pragma omp allocate(g3) allocator(omp_const_mem_alloc)
 #pragma omp allocate(g4) allocator(omp_high_bw_mem_alloc)
 #pragma omp allocate(g5) allocator(omp_low_lat_mem_alloc)
 #pragma omp allocate(g6) allocator(omp_cgroup_mem_alloc)  // { dg-error 
"'allocator' clause for static variable 'g6' must not be 
'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { 
target c } }
+// { dg-error "'allocator' clause must not be 'omp_cgroup_mem_alloc', 
'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { target c++ } .-1 }
 #pragma omp allocate(g7) allocator(omp_pteam_mem_alloc)   // { dg-error 
"'allocator' clause for static variable 'g7' must not be 
'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { 
target c } }
+// { dg-error "'allocator' clause must not be 'omp_cgroup_mem_alloc', 
'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { target c++ } .-1 }
 #pragma omp allocate(g8) allocator(omp_thread_mem_alloc)  // { dg-error 
"'allocator' clause for static variable 'g8' must not be 
'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { 
target c } }
+// { dg-error "'allocator' clause must not be 'omp_cgroup_mem_alloc', 
'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { target c++ } .-1 }
 #pragma omp allocate(g9) allocator(ompx_gnu_pinned_mem_alloc)
 #pragma omp allocate(g10) allocator(ompx_gnu_managed_mem_alloc)
-// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-
 
 void local_static ()
 {
@@ -75,25 +67,18 @@ void local_static ()
   static int s10;
 
   #pragma omp allocate(s0) allocator(omp_null_allocator)  // { dg-error 
"'allocator' clause requires a predefined allocator as 's0' is static" "" { 
target c } }
+// { dg-error "'allocator' clause requires a constant predefined allocator" "" 
{ target c++ } .-1 }
   #pragma omp allocate(s1) allocator(omp_default_mem_alloc)
   #pragma omp allocate(s2) allocator(omp_large_cap_mem_alloc)
   #pragma omp allocate(s3) allocator(omp_const_mem_alloc)
   #pragma omp allocate(s4) allocator(omp_high_bw_mem_alloc)
   #pragma omp allocate(s5) allocator(omp_low_lat_mem_alloc)
   #pragma omp allocate(s6) allocator(omp_cgroup_mem_alloc)  // { dg-error 
"'allocator' clause for static variable 's6' must not be 
'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { 
target c } }
+// { dg-error "'allocator' clause must not be 'omp_cgroup_mem_alloc', 
'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { target c++ } .-1 }
   #pragma omp allocate(s7) allocator(omp_pteam_mem_alloc)   // { dg-error 
"'allocator' clause for static variable 's7' must not be 
'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { 
target c } }
+// { dg-error "'allocator' clause must not be 'omp_cgroup_mem_alloc', 
'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { target c++ } .-1 }
   #pragma omp allocate(s8) allocator(omp_thread_mem_alloc)  // { dg-error 
"'allocator' clause for static variable 's8' must not be 
'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { 
target c } }
+// { dg-error "'allocator' clause must not be 'omp_cgroup_mem_alloc', 
'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { target c++ } .-1 }
   #pragma omp allocate(s9) allocator(ompx_gnu_pinned_mem_alloc)
   #pragma omp allocate(s10) allocator(ompx_gnu_managed_mem_alloc)
-  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
-  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet 
supported" "" { target c++ } .-11 }
 }
diff --git a/gcc/testsuite/g++.dg/gomp/allocate-handles-2.C 
b/gcc/testsuite/g++.dg/gomp/allocate-handles-2.C
index 89949ee0fefb..766c749b2fec 100644
--- a/gcc/testsuite/g++.dg/gomp/allocate-handles-2.C
+++ b/gcc/testsuite/g++.dg/gomp/allocate-handles-2.C
@@ -17,29 +17,28 @@ void test_predefined_alloc()
   #pragma omp allocate(a) allocator(Alloc)
 }
 
+template<omp_allocator_handle_t Alloc>
+void test_predefined_alloc_disallowed()
+{
+  static int a = 42;
+  #pragma omp allocate(a) allocator(Alloc)  // { dg-error "'allocator' clause 
must not be 'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc', or 
'omp_thread_mem_alloc'" }
+}
+
 /* Because this is written to work as far back as c++11 it is a little bit
    crusty.  It is metaprogrammed to automatically test the full ranges
    specified above.  */
 
-template<omp_allocator_handle_t...>
-struct sequence {};
-
-template<__UINTPTR_TYPE__ Offset, __UINTPTR_TYPE__... Is>
-using modified = sequence<static_cast<omp_allocator_handle_t>(Is + Offset)...>;
-
-template<__UINTPTR_TYPE__ Start, __UINTPTR_TYPE__ End>
-using make_offset_sequence = modified<Start, __integer_pack(End - Start)...>;
-
-template<omp_allocator_handle_t... Allocs>
-void unpack(sequence<Allocs...>)
-{
-  int helper[] = {(test_predefined_alloc<Allocs>(), 0)...};
-}
-
 void do_tests()
 {
-  /* make_sequence creates a sequence [Start, End) while the *_MAX values are
-     inclusive, add 1 to the End arg to create an exclusive range.  */
-  unpack(make_offset_sequence<1, GOMP_OMP_PREDEF_ALLOC_MAX + 1>{});
-  unpack(make_offset_sequence<GOMP_OMPX_PREDEF_ALLOC_MIN, 
GOMP_OMPX_PREDEF_ALLOC_MAX + 1>{});
+  test_predefined_alloc<omp_default_mem_alloc> ();
+  test_predefined_alloc<omp_large_cap_mem_alloc> ();
+  test_predefined_alloc<omp_const_mem_alloc> ();
+  test_predefined_alloc<omp_high_bw_mem_alloc> ();
+  test_predefined_alloc<omp_low_lat_mem_alloc> ();
+
+  /* These are expected to give an error because they don't make sense
+     on static variables.  See PR122892.  */
+  test_predefined_alloc_disallowed<omp_cgroup_mem_alloc> ();  // { dg-message 
"required from here" }
+  test_predefined_alloc_disallowed<omp_pteam_mem_alloc> ();  // { dg-message 
"required from here" }
+  test_predefined_alloc_disallowed<omp_thread_mem_alloc> ();  // { dg-message 
"required from here" }
 }

Reply via email to