From 5a6b1d8ef4218a1a2ed6d43c6ee058db9c417bc8 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 30 Oct 2020 09:16:45 +0100 Subject: [PATCH] openmp: Handle non-static data members in allocate clause and other C++ allocate fixes This allows specification of non-static data members in allocate clause like it can be specified in other privatization clauses and adds a new testcase that covers also handling of that clause in templates. 2020-10-30 Jakub Jelinek * semantics.c (finish_omp_clauses) : Handle non-static members in methods. * pt.c (tsubst_omp_clauses): Handle OMP_CLAUSE_ALLOCATE. * c-c++-common/gomp/allocate-1.c (qux): Add another test. * g++.dg/gomp/allocate-1.C: New test. --- gcc/cp/pt.c | 1 + gcc/cp/semantics.c | 33 +++++--- gcc/testsuite/c-c++-common/gomp/allocate-1.c | 8 ++ gcc/testsuite/g++.dg/gomp/allocate-1.C | 88 ++++++++++++++++++++ 4 files changed, 117 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/g++.dg/gomp/allocate-1.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b569644514c..aa162d2a4f9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -17390,6 +17390,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort, case OMP_CLAUSE_IS_DEVICE_PTR: case OMP_CLAUSE_INCLUSIVE: case OMP_CLAUSE_EXCLUSIVE: + case OMP_CLAUSE_ALLOCATE: /* tsubst_expr on SCOPE_REF results in returning finish_non_static_data_member result. Undo that here. */ if (TREE_CODE (OMP_CLAUSE_DECL (oc)) == SCOPE_REF diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index d8d3baf9249..352ebe03436 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -7200,7 +7200,11 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) break; case OMP_CLAUSE_ALLOCATE: - t = OMP_CLAUSE_DECL (c); + t = omp_clause_decl_field (OMP_CLAUSE_DECL (c)); + if (t) + omp_note_field_privatization (t, OMP_CLAUSE_DECL (c)); + else + t = OMP_CLAUSE_DECL (c); if (t == current_class_ptr) { error_at (OMP_CLAUSE_LOCATION (c), @@ -7208,7 +7212,9 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) remove = true; break; } - if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL) + if (!VAR_P (t) + && TREE_CODE (t) != PARM_DECL + && TREE_CODE (t) != FIELD_DECL) { if (processing_template_decl && TREE_CODE (t) != OVERLOAD) break; @@ -7232,17 +7238,18 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) bitmap_set_bit (&aligned_head, DECL_UID (t)); allocate_seen = true; } - t = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c); - if (error_operand_p (t)) + tree allocator; + allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c); + if (error_operand_p (allocator)) { remove = true; break; } - if (t == NULL_TREE) - break; + if (allocator == NULL_TREE) + goto handle_field_decl; tree allocatort; - allocatort = TYPE_MAIN_VARIANT (TREE_TYPE (t)); - if (!type_dependent_expression_p (t) + allocatort = TYPE_MAIN_VARIANT (TREE_TYPE (allocator)); + if (!type_dependent_expression_p (allocator) && (TREE_CODE (allocatort) != ENUMERAL_TYPE || TYPE_NAME (allocatort) == NULL_TREE || TREE_CODE (TYPE_NAME (allocatort)) != TYPE_DECL @@ -7254,17 +7261,17 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) error_at (OMP_CLAUSE_LOCATION (c), "% clause allocator expression has " "type %qT rather than %", - TREE_TYPE (t)); + TREE_TYPE (allocator)); remove = true; } else { - t = mark_rvalue_use (t); + allocator = mark_rvalue_use (allocator); if (!processing_template_decl) - t = maybe_constant_value (t); - OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = t; + allocator = maybe_constant_value (allocator); + OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator; } - break; + goto handle_field_decl; case OMP_CLAUSE_DEPEND: t = OMP_CLAUSE_DECL (c); diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-1.c b/gcc/testsuite/c-c++-common/gomp/allocate-1.c index 29ebdf1a79a..5630dac3334 100644 --- a/gcc/testsuite/c-c++-common/gomp/allocate-1.c +++ b/gcc/testsuite/c-c++-common/gomp/allocate-1.c @@ -74,3 +74,11 @@ foo (int x, int z) r += bar (x, &r, 0); #pragma omp taskwait } + +void +qux (const omp_allocator_handle_t h) +{ + int x = 0; + #pragma omp parallel firstprivate (x) allocate (h: x) + x = 1; +} diff --git a/gcc/testsuite/g++.dg/gomp/allocate-1.C b/gcc/testsuite/g++.dg/gomp/allocate-1.C new file mode 100644 index 00000000000..e70c65e3d2b --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/allocate-1.C @@ -0,0 +1,88 @@ +// { dg-do compile } +// { dg-additional-options "-std=c++11" } + +typedef enum omp_allocator_handle_t +#if __cplusplus >= 201103L +: __UINTPTR_TYPE__ +#endif +{ + 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, + __omp_allocator_handle_t_max__ = __UINTPTR_MAX__ +} omp_allocator_handle_t; + +namespace N1 +{ + using ::omp_allocator_handle_t; + void + foo (const omp_allocator_handle_t h) + { + int x = 0; + #pragma omp parallel allocate (h: x) private (x) + x = 1; + } +} + +namespace N2 +{ + typedef enum omp_allocator_handle_t { my = 0 } omp_allocator_handle_t; + void + foo (omp_allocator_handle_t h) + { + int x = 0; + #pragma omp parallel allocate (h: x) private (x) // { dg-error "'allocate' clause allocator expression has type 'N2::omp_allocator_handle_t' rather than 'omp_allocator_handle_t'" } + x = 1; + } +} + +struct S +{ + void foo () + { + #pragma omp parallel allocate (omp_default_mem_alloc:s) firstprivate (s) + s++; + } + int s; +}; + +template +struct U +{ + int foo () + { + #pragma omp parallel allocate (omp_default_mem_alloc:s) firstprivate (s) + s++; + return 1; + } + T s; +}; + +template +int foo (T t) +{ + int x = 0; + #pragma omp parallel firstprivate (x) allocate (t: x) + x = 1; + return 0; +} + +template +int bar (T t) +{ + int x = 0; + #pragma omp parallel firstprivate (x) allocate (t: x) // { dg-error "'allocate' clause allocator expression has type 'int' rather than 'omp_allocator_handle_t'" } + x = 1; + return 0; +} + +omp_allocator_handle_t h; +int a = foo (h); +int b = bar (0); +int c = U ().foo (); -- 2.30.2