This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[committed] Fix OpenMP template instantiation issue (PR c++/66571)


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  <jakub@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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]