openmp: Handle non-static data members in allocate clause and other C++ allocate...
authorJakub Jelinek <jakub@redhat.com>
Fri, 30 Oct 2020 08:16:45 +0000 (09:16 +0100)
committerJakub Jelinek <jakub@redhat.com>
Fri, 30 Oct 2020 08:16:45 +0000 (09:16 +0100)
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  <jakub@redhat.com>

* semantics.c (finish_omp_clauses) <case OMP_CLAUSE_ALLOCATE>: 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
gcc/cp/semantics.c
gcc/testsuite/c-c++-common/gomp/allocate-1.c
gcc/testsuite/g++.dg/gomp/allocate-1.C [new file with mode: 0644]

index b569644514c7d3fce96338e515796749cccc368a..aa162d2a4f9f9f858db1ae8c32a24ff780b93899 100644 (file)
@@ -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
index d8d3baf92493ba4f83ed7c8e4f436b49303a8bb5..352ebe03436f23e574e748570c6dc724e79038b7 100644 (file)
@@ -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),
                        "%<allocate%> clause allocator expression has "
                        "type %qT rather than %<omp_allocator_handle_t%>",
-                       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);
index 29ebdf1a79aaacb998950c2060b7f061b838dd48..5630dac333427228bd3d7c0d80a9cd5301a1ad64 100644 (file)
@@ -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 (file)
index 0000000..e70c65e
--- /dev/null
@@ -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 <typename T>
+struct U
+{
+  int foo ()
+  {
+    #pragma omp parallel allocate (omp_default_mem_alloc:s) firstprivate (s)
+    s++;
+    return 1;
+  }
+  T s;
+};
+
+template <typename T>
+int foo (T t)
+{
+  int x = 0;
+  #pragma omp parallel firstprivate (x) allocate (t: x)
+  x = 1;
+  return 0;
+}
+
+template <typename T>
+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<int> ().foo ();