diff mbox

[gomp4.1] Fix OpenMP template instantiation issue (PR c++/66571)

Message ID 20150618094553.GU10247@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek June 18, 2015, 9:45 a.m. UTC
Hi!

I've merged trunk into gomp-4_1-branch up to r224573.
Unfortunately, the PR66571 patch doesn't really work on the branch where we
support privatization of non-static data members.  Therefore, I've committed
together with the merge following change plus another testcase that
covers the new clauses that previously didn't allow references.

2015-06-18  Jakub Jelinek  <jakub@redhat.com>

	PR c++/66571
	* pt.c (tsubst_omp_clause_decl): Use tsubst_expr instead of
	tsubst_copy.  Undo convert_from_reference if non-REFERENCE_REF_P
	became REFERENCE_REF_P after tsubst_expr.
	(tsubst_omp_clauses): Use tsubst_omp_clause_decl instead of
	tsubst_copy for OMP_CLAUSE_DECL on all clauses.  Remove earlier
	INDIRECT_REF adjustments in the allow_fields handling.

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


	Jakub
diff mbox

Patch

--- gcc/cp/pt.c.jj	2015-06-17 21:21:10.000000000 +0200
+++ gcc/cp/pt.c	2015-06-18 10:57:22.750541798 +0200
@@ -13512,7 +13512,14 @@  tsubst_omp_clause_decl (tree decl, tree
 	return decl;
       return tree_cons (low_bound, length, chain);
     }
-  return tsubst_copy (decl, args, complain, in_decl);
+  tree ret = tsubst_expr (decl, args, complain, in_decl,
+			  /*integral_constant_expression_p=*/false);
+  /* Undo convert_from_reference tsubst_expr could have called.  */
+  if (decl
+      && REFERENCE_REF_P (ret)
+      && !REFERENCE_REF_P (decl))
+    ret = TREE_OPERAND (ret, 0);
+  return ret;
 }
 
 /* Like tsubst_copy, but specifically for OpenMP clauses.  */
@@ -13547,9 +13554,6 @@  tsubst_omp_clauses (tree clauses, bool d
 	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:
@@ -13593,13 +13597,15 @@  tsubst_omp_clauses (tree clauses, bool d
 	      else
 		gcc_assert (identifier_p (placeholder));
 	    }
-	  OMP_CLAUSE_DECL (nc) = tsubst_copy (OMP_CLAUSE_DECL (oc), args,
-					      complain, in_decl);
+	  OMP_CLAUSE_DECL (nc)
+	    = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain,
+				      in_decl);
 	  break;
 	case OMP_CLAUSE_LINEAR:
 	case OMP_CLAUSE_ALIGNED:
-	  OMP_CLAUSE_DECL (nc) = tsubst_copy (OMP_CLAUSE_DECL (oc), args,
-					      complain, in_decl);
+	  OMP_CLAUSE_DECL (nc)
+	    = tsubst_omp_clause_decl (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);
@@ -13638,16 +13644,6 @@  tsubst_omp_clauses (tree clauses, bool d
 		    == IDENTIFIER_NODE))
 	      {
 		tree t = OMP_CLAUSE_DECL (nc);
-		if (TREE_CODE (t) == INDIRECT_REF)
-		  t = TREE_OPERAND (t, 0);
-		if (TREE_CODE (t) != COMPONENT_REF)
-		  {
-		    if (VAR_P (t)
-			&& DECL_LANG_SPECIFIC (t)
-			&& DECL_OMP_PRIVATIZED_MEMBER (t))
-		      OMP_CLAUSE_DECL (nc) = t;
-		    break;
-		  }
 		tree v = t;
 		while (v)
 		  switch (TREE_CODE (v))
@@ -13677,14 +13673,11 @@  tsubst_omp_clauses (tree clauses, bool d
 		     && DECL_OMP_PRIVATIZED_MEMBER (OMP_CLAUSE_DECL (oc)))
 	      {
 		tree decl = OMP_CLAUSE_DECL (nc);
-		if (TREE_CODE (decl) == INDIRECT_REF)
-		  decl = TREE_OPERAND (decl, 0);
 		if (VAR_P (decl))
 		  {
 		    if (!DECL_LANG_SPECIFIC (decl))
 		      retrofit_lang_decl (decl);
 		    DECL_OMP_PRIVATIZED_MEMBER (decl) = 1;
-		    OMP_CLAUSE_DECL (nc) = decl;
 		  }
 	      }
 	    break;
--- gcc/testsuite/g++.dg/gomp/pr66571-2.C.jj	2015-06-18 11:05:17.837255437 +0200
+++ gcc/testsuite/g++.dg/gomp/pr66571-2.C	2015-06-18 11:05:29.913070275 +0200
@@ -0,0 +1,36 @@ 
+// PR c++/66571
+// { dg-do compile }
+// { dg-options "-fopenmp" }
+
+template <typename T>
+extern void bar (T, T, T, T);
+
+template <typename T>
+void
+foo (T a, T b, T c, T d)
+{
+  #pragma omp parallel for simd private (a) firstprivate (b) lastprivate (c) linear (d:2)
+  for (int i = 0; i < 10; i++)
+    bar<T> (a, b, c, d), d += 2;
+  #pragma omp parallel private (c)
+    #pragma omp single copyprivate (c)
+      bar<T> (a, b, c, d);
+  T e = a;
+  T f = b;
+  T g = c;
+  T h = d;
+  #pragma omp parallel for simd private (e) firstprivate (f) lastprivate (g) linear (h:2)
+  for (int i = 0; i < 10; i++)
+    bar<T> (e, f, g, h), h += 2;
+  #pragma omp parallel private (g)
+    #pragma omp single copyprivate (g)
+      bar<T> (e, f, g, h);
+}
+
+void
+baz ()
+{
+  int a = 0, b = 0, c = 0, d = 0;
+  foo <int> (a, b, c, d);
+  foo <int &> (a, b, c, d);
+}