OpenACC has slightly different data semantics for reference types and
pointers. Without this patch, omp-low was treating all references types
like pointers which resulted in some gimple type checking errors when
checking is enabled. It turned out that Chung-Lin had resolved the issue
way back in gomp-4_0-branch for PR77371, but that fix never made its way
into trunk. The gimplifier stuff is not relevant to this PR, but I left
it in there because it does address the original issue in PR77371.

I tested this patch from og8 on trunk on x86_64 / nvptx offloading, and
the results came back clean. It this OK for trunk?

Thanks,
Cesar
2018-05-31  Chung-Lin Tang  <clt...@codesourcery.com>
	    Cesar Philippidis  <ce...@codesourcery.com>

	PR middle-end/85879

	gcc/
	* gimplify.c (gimplify_adjust_omp_clauses): Add 'remove = true'
	when emitting error on private/firstprivate reductions.
	* omp-low.c (lower_omp_target): Avoid reference-type processing
	on pointers for firstprivate clause.

	gcc/testsuite/
	* gfortran.dg/goacc/pr77371-1.f90: New test.
	* gfortran.dg/goacc/pr77371-2.f90: New test.
	* gfortran.dg/goacc/pr85879.f90: New test.


diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 9771804f27e..44cb784620a 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -9275,13 +9275,16 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
 	case OMP_CLAUSE_REDUCTION:
 	  decl = OMP_CLAUSE_DECL (c);
 	  /* OpenACC reductions need a present_or_copy data clause.
-	     Add one if necessary.  Error is the reduction is private.  */
+	     Add one if necessary.  Emit error when the reduction is private.  */
 	  if (ctx->region_type == ORT_ACC_PARALLEL)
 	    {
 	      n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
 	      if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
-		error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
-			  "reduction on %qE", DECL_NAME (decl));
+		{
+		  remove = true;
+		  error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
+			    "reduction on %qE", DECL_NAME (decl));
+		}
 	      else if ((n->value & GOVD_MAP) == 0)
 		{
 		  tree next = OMP_CLAUSE_CHAIN (c);
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index d8588b9faed..ba6c705cf8b 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -7700,7 +7700,8 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 	    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
 	      {
 		gcc_assert (is_gimple_omp_oacc (ctx->stmt));
-		if (omp_is_reference (new_var))
+		if (omp_is_reference (new_var)
+		    && TREE_CODE (TREE_TYPE (new_var)) != POINTER_TYPE)
 		  {
 		    /* Create a local object to hold the instance
 		       value.  */
diff --git a/gcc/testsuite/gfortran.dg/goacc/pr77371-1.f90 b/gcc/testsuite/gfortran.dg/goacc/pr77371-1.f90
new file mode 100644
index 00000000000..11c29ba3e6d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/pr77371-1.f90
@@ -0,0 +1,9 @@
+! PR fortran/77371
+! { dg-do compile }
+program p
+  character(:), allocatable :: z
+  !$acc parallel
+  z = 'abc' 
+  !$acc end parallel
+  print *, z
+end
diff --git a/gcc/testsuite/gfortran.dg/goacc/pr77371-2.f90 b/gcc/testsuite/gfortran.dg/goacc/pr77371-2.f90
new file mode 100644
index 00000000000..9d42c17ac4e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/pr77371-2.f90
@@ -0,0 +1,7 @@
+! PR fortran/77371
+! { dg-do compile }
+program p
+   integer, allocatable :: n
+!$acc parallel reduction (+:n) private(n) ! { dg-error "invalid private reduction" }
+!$acc end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/goacc/pr85879.f90 b/gcc/testsuite/gfortran.dg/goacc/pr85879.f90
new file mode 100644
index 00000000000..cd50be2fdb4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/pr85879.f90
@@ -0,0 +1,12 @@
+! PR middle-end/85879
+! { dg-do compile }
+
+program p
+   integer, pointer :: i
+   integer, target :: j
+   j = 2
+   i => j
+   !$acc parallel
+   j = i
+   !$acc end parallel
+end

Reply via email to