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" } }
