[gcc/devel/omp/gcc-16] OpenMP, C++: Diagnose inappropriate allocators for static variables [PR122892]

Sandra Loosemore via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
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" }
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.