re PR c++/66571 (Template substitution causes some OpenMP rejects-valid)
authorJakub Jelinek <jakub@redhat.com>
Wed, 17 Jun 2015 18:01:05 +0000 (20:01 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 17 Jun 2015 18:01:05 +0000 (20:01 +0200)
PR c++/66571
* pt.c (tsubst_omp_clause_decl): New function.
(tsubst_omp_clauses): Use it or tsubst_copy instead of
tsubst_expr on OMP_CLAUSE_DECL.

* g++.dg/gomp/pr66571-1.C: New test.

From-SVN: r224569

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/gomp/pr66571-1.C [new file with mode: 0644]

index 98dab4a47b9333a1f05ce9d7a392f4c01519f300..010442fadfd2bf17238dd935b1e53375835c0782 100644 (file)
@@ -1,3 +1,8 @@
+2015-06-17  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/66571
+       * g++.dg/gomp/pr66571-1.C: New test.
+
 2015-06-17  Andrew MacLeod  <amacleod@redhat.com>
 
        * cp-lang.c (cxx_dwarf_name): Use anon_aggrname_p.
@@ -7,7 +12,6 @@
        * pt.c (push_template_decl_real): Likewise.
        * name-lookup.c (make_anon_name): Use anon_aggrname_format.
 
-
 2015-06-17  Andrew MacLeod  <amacleod@redhat.com>
 
        * call.c: Do not include input.h, line-map.h or is-a.h.
index 60b94981b0ad03e75e072f8803ad16066dcd1919..ccce90dba954fa6993219115a607d7c211de51d6 100644 (file)
@@ -13489,6 +13489,32 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     }
 }
 
+/* Helper function for tsubst_omp_clauses, used for instantiation of
+   OMP_CLAUSE_DECL of clauses that handles also OpenMP array sections
+   represented with TREE_LIST.  */
+
+static tree
+tsubst_omp_clause_decl (tree decl, tree args, tsubst_flags_t complain,
+                       tree in_decl)
+{
+  if (TREE_CODE (decl) == TREE_LIST)
+    {
+      tree low_bound
+       = tsubst_expr (TREE_PURPOSE (decl), args, complain, in_decl,
+                      /*integral_constant_expression_p=*/false);
+      tree length = tsubst_expr (TREE_VALUE (decl), args, complain, in_decl,
+                                /*integral_constant_expression_p=*/false);
+      tree chain = tsubst_omp_clause_decl (TREE_CHAIN (decl), args, complain,
+                                          in_decl);
+      if (TREE_PURPOSE (decl) == low_bound
+         && TREE_VALUE (decl) == length
+         && TREE_CHAIN (decl) == chain)
+       return decl;
+      return tree_cons (low_bound, length, chain);
+    }
+  return tsubst_copy (decl, args, complain, in_decl);
+}
+
 /* Like tsubst_copy, but specifically for OpenMP clauses.  */
 
 static tree
@@ -13520,16 +13546,23 @@ tsubst_omp_clauses (tree clauses, bool declare_simd,
        case OMP_CLAUSE_FIRSTPRIVATE:
        case OMP_CLAUSE_COPYIN:
        case OMP_CLAUSE_COPYPRIVATE:
+       case OMP_CLAUSE_UNIFORM:
+         OMP_CLAUSE_DECL (nc) = tsubst_copy (OMP_CLAUSE_DECL (oc), args,
+                                             complain, in_decl);
+         break;
+       case OMP_CLAUSE_DEPEND:
+       case OMP_CLAUSE_FROM:
+       case OMP_CLAUSE_TO:
+       case OMP_CLAUSE_MAP:
+         OMP_CLAUSE_DECL (nc)
+           = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain,
+                                     in_decl);
+         break;
        case OMP_CLAUSE_IF:
        case OMP_CLAUSE_NUM_THREADS:
        case OMP_CLAUSE_SCHEDULE:
        case OMP_CLAUSE_COLLAPSE:
        case OMP_CLAUSE_FINAL:
-       case OMP_CLAUSE_DEPEND:
-       case OMP_CLAUSE_FROM:
-       case OMP_CLAUSE_TO:
-       case OMP_CLAUSE_UNIFORM:
-       case OMP_CLAUSE_MAP:
        case OMP_CLAUSE_DEVICE:
        case OMP_CLAUSE_DIST_SCHEDULE:
        case OMP_CLAUSE_NUM_TEAMS:
@@ -13556,20 +13589,17 @@ tsubst_omp_clauses (tree clauses, bool declare_simd,
              else
                gcc_assert (identifier_p (placeholder));
            }
-         OMP_CLAUSE_OPERAND (nc, 0)
-           = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain,
-                          in_decl, /*integral_constant_expression_p=*/false);
+         OMP_CLAUSE_DECL (nc) = tsubst_copy (OMP_CLAUSE_DECL (oc), args,
+                                             complain, in_decl);
          break;
        case OMP_CLAUSE_LINEAR:
        case OMP_CLAUSE_ALIGNED:
-         OMP_CLAUSE_OPERAND (nc, 0)
-           = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain,
-                          in_decl, /*integral_constant_expression_p=*/false);
+         OMP_CLAUSE_DECL (nc) = tsubst_copy (OMP_CLAUSE_DECL (oc), args,
+                                             complain, in_decl);
          OMP_CLAUSE_OPERAND (nc, 1)
            = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 1), args, complain,
                           in_decl, /*integral_constant_expression_p=*/false);
          break;
-
        case OMP_CLAUSE_NOWAIT:
        case OMP_CLAUSE_ORDERED:
        case OMP_CLAUSE_DEFAULT:
index 10c61ef2cf676536e2e4603c47ed0b5fa568dfb8..7d774cb7e82ab8dbcf1834356aec011b55b1f823 100644 (file)
@@ -1,5 +1,8 @@
 2015-06-17  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/66571
+       * g++.dg/gomp/pr66571-1.C: New test.
+
        PR middle-end/66429
        * c-c++-common/gomp/pr66429.c: New test.
 
diff --git a/gcc/testsuite/g++.dg/gomp/pr66571-1.C b/gcc/testsuite/g++.dg/gomp/pr66571-1.C
new file mode 100644 (file)
index 0000000..9fa9ab6
--- /dev/null
@@ -0,0 +1,37 @@
+// PR c++/66571
+// { dg-do compile }
+// { dg-options "-fopenmp" }
+
+template <typename T, typename U>
+extern void bar (T, T, U);
+
+template <typename T, typename U>
+void
+foo (T a, T b, U c)
+{
+  #pragma omp parallel for simd shared (a, c) reduction (+:b)
+  for (int i = 0; i < 10; i++)
+    bar<T> (a, b, c);
+  #pragma omp target map(tofrom:a, c[0:5])
+    ;
+  #pragma omp task depend(inout:c[4:2])
+    ;
+  T d = a;
+  T e = b;
+  U f = c;
+  #pragma omp parallel for simd shared (d, f) reduction (+:e)
+  for (int i = 0; i < 10; i++)
+    bar<T> (d, e, f);
+  #pragma omp target map(tofrom:d, f[0:5])
+    ;
+  #pragma omp task depend(inout:f[4:2])
+    ;
+}
+
+void
+baz ()
+{
+  int a = 0, b = 0, cb[10] = {}, *c = cb;
+  foo <int, int *> (a, b, c);
+  foo <int &, int *&> (a, b, c);
+}