From a55b64d3dbc7e6c9c649f7f3d23e72a0a8712ee0 Mon Sep 17 00:00:00 2001
From: Thomas Schwinge <thomas@codesourcery.com>
Date: Tue, 4 Jun 2019 20:25:41 +0200
Subject: [PATCH] [PR90743] Fortran 'allocatable' with OpenACC data/OpenMP
 'target' 'map' clauses

Test what OpenMP 5.0 has to say on this topic.  And make OpenACC do the same.

	libgomp/
	PR fortran/90743
	* oacc-parallel.c (GOACC_parallel_keyed): Handle NULL case.
	* testsuite/libgomp.fortran/target-allocatable-1.f90: New file.
	* testsuite/libgomp.oacc-fortran/allocatable-1.f90: New file.
---
 libgomp/oacc-parallel.c                       |  9 ++-
 .../libgomp.fortran/target-allocatable-1.f90  |  8 +++
 .../libgomp.oacc-fortran/allocatable-1.f90    | 70 +++++++++++++++++++
 3 files changed, 84 insertions(+), 3 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.fortran/target-allocatable-1.f90
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/allocatable-1.f90

diff --git a/libgomp/oacc-parallel.c b/libgomp/oacc-parallel.c
index e56330f6226b..0c2cfa05a438 100644
--- a/libgomp/oacc-parallel.c
+++ b/libgomp/oacc-parallel.c
@@ -325,9 +325,12 @@ GOACC_parallel_keyed (int flags_m, void (*fn) (void *),
   
   devaddrs = gomp_alloca (sizeof (void *) * mapnum);
   for (i = 0; i < mapnum; i++)
-    devaddrs[i] = (void *) (tgt->list[i].key->tgt->tgt_start
-			    + tgt->list[i].key->tgt_offset
-			    + tgt->list[i].offset);
+    if (tgt->list[i].key != NULL)
+      devaddrs[i] = (void *) (tgt->list[i].key->tgt->tgt_start
+			      + tgt->list[i].key->tgt_offset
+			      + tgt->list[i].offset);
+    else
+      devaddrs[i] = NULL;
   if (aq == NULL)
     acc_dev->openacc.exec_func (tgt_fn, mapnum, hostaddrs, devaddrs, dims,
 				tgt);
diff --git a/libgomp/testsuite/libgomp.fortran/target-allocatable-1.f90 b/libgomp/testsuite/libgomp.fortran/target-allocatable-1.f90
new file mode 100644
index 000000000000..9f0b7f0c3b53
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target-allocatable-1.f90
@@ -0,0 +1,8 @@
+! Test 'allocatable' with OpenMP 'target' 'map' clauses.
+
+! { dg-do run }
+! { dg-additional-options "-cpp" }
+! { dg-additional-options "-DACC_MEM_SHARED=0" { target offload_device_nonshared_as } }
+! { dg-additional-options "-DACC_MEM_SHARED=1" { target offload_device_shared_as } }
+
+#include "../libgomp.oacc-fortran/allocatable-1.f90"
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/allocatable-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/allocatable-1.f90
new file mode 100644
index 000000000000..0941f71f8c30
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/allocatable-1.f90
@@ -0,0 +1,70 @@
+! Test 'allocatable' with OpenACC data clauses.
+
+! This is also 'include'd from '../libgomp.fortran/target-allocatable-1.f90'.
+
+! { dg-do run }
+! { dg-additional-options "-cpp" }
+
+program main
+  implicit none
+  integer, allocatable :: a, b, c, d, e
+
+  allocate (a)
+  a = 11
+
+  b = 25 ! Implicit allocation.
+
+  c = 52 ! Implicit allocation.
+
+  !No 'allocate (d)' here.
+
+  !No 'allocate (e)' here.
+
+  !$omp target map(to: a) map(tofrom: b, c, d) map(from: e)
+  !$acc parallel copyin(a) copy(b, c, d) copyout(e)
+
+  if (.not. allocated (a)) stop 1
+  if (a .ne. 11) stop 2
+  a = 33
+ 
+  if (.not. allocated (b)) stop 3
+  if (b .ne. 25) stop 4
+ 
+  if (.not. allocated (c)) stop 5
+  if (c .ne. 52) stop 6
+  c = 10
+ 
+  if (allocated (d)) stop 7
+  d = 42 ! Implicit allocation, but on device only.
+  if (.not. allocated (d)) stop 8
+  deallocate (d) ! OpenMP requires must be "unallocated upon exit from the region".
+
+  if (allocated (e)) stop 9
+  e = 24 ! Implicit allocation, but on device only.
+  if (.not. allocated (e)) stop 10
+  deallocate (e) ! OpenMP requires must be "unallocated upon exit from the region".
+
+  !$acc end parallel
+  !$omp end target
+
+  if (.not. allocated (a)) stop 20
+#if ACC_MEM_SHARED
+  if (a .ne. 33) stop 21
+#else
+  if (a .ne. 11) stop 22
+#endif
+  deallocate (a)
+
+  if (.not. allocated (b)) stop 23
+  if (b .ne. 25) stop 24
+  deallocate (b)
+
+  if (.not. allocated (c)) stop 25
+  if (c .ne. 10) stop 26
+  deallocate (c)
+
+  if (allocated (d)) stop 27
+
+  if (allocated (e)) stop 28
+
+end program main
-- 
2.17.1

