}
}
+/* 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
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:
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:
--- /dev/null
+// 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);
+}