@@ -1587,6 +1587,7 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool openacc)
return;
tree decl = OMP_CLAUSE_DECL (c);
+ bool assumed_size = false;
/* Assumed-size arrays can't be mapped implicitly, they have to be
mapped explicitly using array sections. */
@@ -1597,9 +1598,14 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool openacc)
GFC_TYPE_ARRAY_RANK (TREE_TYPE (decl)) - 1)
== NULL)
{
- error_at (OMP_CLAUSE_LOCATION (c),
- "implicit mapping of assumed size array %qD", decl);
- return;
+ if (openacc)
+ assumed_size = true;
+ else
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "implicit mapping of assumed size array %qD", decl);
+ return;
+ }
}
if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FORCE_DEVICEPTR)
@@ -1654,7 +1660,9 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool openacc)
else
{
OMP_CLAUSE_DECL (c) = decl;
- OMP_CLAUSE_SIZE (c) = NULL_TREE;
+ OMP_CLAUSE_SIZE (c) = assumed_size ? size_zero_node : NULL_TREE;
+ if (assumed_size)
+ OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
}
if (TREE_CODE (TREE_TYPE (orig_decl)) == REFERENCE_TYPE
&& (GFC_DECL_GET_SCALAR_POINTER (orig_decl)
@@ -4,7 +4,8 @@
! exit data, respectively.
! This does not appear to be supported by the OpenACC standard as of version
-! 3.0. Check for an appropriate error message.
+! 3.0. There is however real-world code that relies on this working, so we
+! make an attempt to support it.
program test
implicit none
@@ -26,7 +27,6 @@ subroutine dtest (a, n)
!$acc enter data copyin(a(1:n))
!$acc parallel loop
-! { dg-error {implicit mapping of assumed size array 'a'} "" { target *-*-* } .-1 }
do i = 1, n
a(i) = i
end do
new file mode 100644
@@ -0,0 +1,28 @@
+! { dg-do run }
+
+program p
+implicit none
+integer :: myarr(10)
+
+myarr = 0
+
+call subr(myarr)
+
+if (myarr(5).ne.5) stop 1
+
+contains
+
+subroutine subr(arr)
+implicit none
+integer :: arr(*)
+
+!$acc enter data copyin(arr(1:10))
+
+!$acc serial
+arr(5) = 5
+!$acc end serial
+
+!$acc exit data copyout(arr(1:10))
+
+end subroutine subr
+end program p
new file mode 100644
@@ -0,0 +1,40 @@
+! { dg-do run }
+
+program p
+implicit none
+integer :: myarr(10)
+
+myarr = 0
+
+call subr(myarr)
+
+if (myarr(5).ne.5) stop 1
+
+contains
+
+subroutine subr(arr)
+implicit none
+integer :: arr(*)
+
+! At first glance, it might not be obvious how this works. The "enter data"
+! and "exit data" operations expand to a pair of mapping nodes for OpenACC,
+! GOMP_MAP_{TO/FROM} and GOMP_MAP_POINTER. The former maps the array data,
+! and the latter creates a separate mapping on the target for the pointer
+! itself with a bias so it represents the "zeroth" element.
+
+!$acc enter data copyin(arr(2:8))
+
+! ...then this implicit mapping creates a zero-length array section
+! (GOMP_MAP_ZERO_LEN_ARRAY_SECTION) followed by another GOMP_MAP_POINTER for
+! 'arr'. But now that pointer is already "present" on the target, so is not
+! overwritten.
+
+!$acc serial
+! This access is then done via the on-target pointer.
+arr(5) = 5
+!$acc end serial
+
+!$acc exit data copyout(arr(2:8))
+
+end subroutine subr
+end program p