Hi!

I've committed (yesterday already) the following patch to trunk and 5 branch
to fix an issue where tsubst_expr on OMP_CLAUSE_DECL, when a decl had
non-reference dependent type, got a reference type after instantiation
and tsubst_expr added convert_from_reference around it.

Bootstrapped/regtested on x86_64-linux and i686-linux.

2015-06-17  Jakub Jelinek  <ja...@redhat.com>

        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.

--- gcc/cp/pt.c.jj      2015-06-17 15:18:40.000000000 +0200
+++ gcc/cp/pt.c 2015-06-17 17:39:01.793799371 +0200
@@ -13490,6 +13490,32 @@ tsubst_copy (tree t, tree args, tsubst_f
     }
 }
 
+/* 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
@@ -13521,16 +13547,23 @@ tsubst_omp_clauses (tree clauses, bool d
        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:
@@ -13557,20 +13590,17 @@ tsubst_omp_clauses (tree clauses, bool d
              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:
--- gcc/testsuite/g++.dg/gomp/pr66571-1.C.jj    2015-06-17 16:44:26.401206652 
+0200
+++ gcc/testsuite/g++.dg/gomp/pr66571-1.C       2015-06-17 16:44:44.487927628 
+0200
@@ -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);
+}

        Jakub

Reply via email to