I introduced a subtle bug in my fix for pr70828. That PR involved
implicit data mappings of subarrays which the user had explicitly mapped
inside an enclosing acc data region. E.g.

  #pragma acc data copy(a[5:10])
  {
    #pragma acc parallel loop
    for (...)
      a[i] = ...

My fix for the PR was to duplicate the associated GOMP_MAP_POINTER
clause for that subarray in the enclosing data region in the parallel
region. However, the code inside gomp_needs_present_data doesn't check
whether the decl in the GOMP_MAP_POINTER clause matches the incoming
decl supplied to this function, which leads to bogus data clauses and
failures at run time. I've applied this patch to gomp-4_0-branch to fix
that.

Cesar
2017-05-11  Cesar Philippidis  <ce...@codesourcery.com>

	gcc/
	* gimplify.c (gomp_needs_data_present): Ensure that the
	correct decl is matched when scanning clauses in the enclosing
	acc data constructs.

	libgomp/
	* testsuite/libgomp.oacc-fortran/implicit_copy.f90: New test.


diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 47fe9ee..5a25dcf 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -7885,10 +7885,15 @@ gomp_needs_data_present (tree decl)
 	break;
 
       for (c = ctx->clauses; c; c = OMP_CLAUSE_CHAIN (c))
-	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
-	    && (omp_clause_matching_array_ref (c, decl)
-		|| OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER))
+	{
+	  if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
+	    continue;
+	  if (omp_clause_matching_array_ref (c, decl))
+	    return c;
+	  else if (OMP_CLAUSE_DECL (c) == decl
+	      && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER)
 	  return c;
+	}
     }
 
   return NULL_TREE;
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/implicit_copy.f90 b/libgomp/testsuite/libgomp.oacc-fortran/implicit_copy.f90
new file mode 100644
index 0000000..f0d4064
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/implicit_copy.f90
@@ -0,0 +1,29 @@
+integer function test()
+  implicit none
+  integer, parameter :: n = 10
+  real(8), dimension(n) :: a, b, c
+  integer i
+
+  do i = 1, n
+     a(i) = i
+     b(i) = 1
+  end do
+
+  !$acc data copyin(a(1:n), b(1:n))
+  !$acc parallel loop
+  do i = 1, n
+     c(i) = a(i) * b(i)
+  end do
+  !$acc end data
+
+  do i = 1, n
+     if (c(i) /= a(i) * b(i)) call abort
+  end do
+end function test
+  
+program main
+  implicit none
+  integer i, test
+  i = test()
+end program main
+

Reply via email to