From d7af812aaca41c3f7425593dcf8c36803e6a1f1e Mon Sep 17 00:00:00 2001
From: Thomas Schwinge <thomas@codesourcery.com>
Date: Fri, 29 May 2020 21:36:27 +0200
Subject: [PATCH] [OpenACC] XFAIL behavior of over-eager 'finalize' clause

	libgomp/
	* testsuite/libgomp.oacc-fortran/deep-copy-6.f90: XFAIL behavior
	of over-eager 'finalize' clause.
	* testsuite/libgomp.oacc-fortran/deep-copy-6-no_finalize.F90: New
	file.
	* testsuite/libgomp.oacc-fortran/mdc-refcount-1-1-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/mdc-refcount-1-1-2.F90: Likewise.
	* testsuite/libgomp.oacc-fortran/mdc-refcount-1-2-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/mdc-refcount-1-2-2.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/mdc-refcount-1-3-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/mdc-refcount-1-3-2.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/mdc-refcount-1-4-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/mdc-refcount-1-4-2.f90: Likewise.

(cherry picked from commit 8d7794c0a2aa6696ab1a91ef209e8a9fe2df56ac)
---
 .../deep-copy-6-no_finalize.F90               |  8 ++++
 .../libgomp.oacc-fortran/deep-copy-6.f90      | 16 +++++++
 .../mdc-refcount-1-1-1.f90                    | 41 +++++++++++++++++
 .../mdc-refcount-1-1-2.F90                    |  9 ++++
 .../mdc-refcount-1-2-1.f90                    | 43 ++++++++++++++++++
 .../mdc-refcount-1-2-2.f90                    | 43 ++++++++++++++++++
 .../mdc-refcount-1-3-1.f90                    | 44 +++++++++++++++++++
 .../mdc-refcount-1-3-2.f90                    | 44 +++++++++++++++++++
 .../mdc-refcount-1-4-1.f90                    | 44 +++++++++++++++++++
 .../mdc-refcount-1-4-2.f90                    | 44 +++++++++++++++++++
 10 files changed, 336 insertions(+)
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/deep-copy-6-no_finalize.F90
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-1-1.f90
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-1-2.F90
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-2-1.f90
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-2-2.f90
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-3-1.f90
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-3-2.f90
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-4-1.f90
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-4-2.f90

diff --git a/libgomp/testsuite/libgomp.oacc-fortran/deep-copy-6-no_finalize.F90 b/libgomp/testsuite/libgomp.oacc-fortran/deep-copy-6-no_finalize.F90
new file mode 100644
index 000000000000..ed4f10e7a3f8
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/deep-copy-6-no_finalize.F90
@@ -0,0 +1,8 @@
+! { dg-do run }
+
+/* Nullify the 'finalize' clause, which disturbs reference counting.  */
+#define finalize
+#include "deep-copy-6.f90"
+
+! { dg-output ".*CheCKpOInT1(\n|\r\n|\r)" }
+! { dg-output ".CheCKpOInT2(\n|\r\n|\r)" }
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/deep-copy-6.f90 b/libgomp/testsuite/libgomp.oacc-fortran/deep-copy-6.f90
index 12910d0d6554..a7943d93d542 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/deep-copy-6.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/deep-copy-6.f90
@@ -3,6 +3,7 @@
 ! Test of attachment counters and finalize.
 
 program dtype
+  use openacc
   implicit none
   integer, parameter :: n = 512
   type mytype
@@ -36,7 +37,22 @@ program dtype
   end do
 !$acc end parallel loop
 
+  if (.not. acc_is_present(var%a(5:n - 5))) stop 11
+  if (.not. acc_is_present(var%b(5:n - 5))) stop 12
+  if (.not. acc_is_present(var)) stop 13
 !$acc exit data copyout(var%a(5:n - 5), var%b(5:n - 5)) finalize
+  if (acc_get_device_type() .ne. acc_device_host) then
+     if (acc_is_present(var%a(5:n - 5))) stop 21
+     if (acc_is_present(var%b(5:n - 5))) stop 22
+  end if
+  print *, "CheCKpOInT1"
+  ! { dg-output ".*CheCKpOInT1(\n|\r\n|\r)" }
+  if (.not. acc_is_present(var)) stop 23
+  !TODO { dg-output "STOP 23(\n|\r\n|\r)$" { target { ! openacc_host_selected } } } ! Scan for what we expect in the "XFAILed" case (without actually XFAILing).
+  !TODO { dg-shouldfail "XFAILed" { ! openacc_host_selected } } ! ... instead of 'dg-xfail-run-if' so that 'dg-output' is evaluated at all.
+  !TODO { dg-final { if { [dg-process-target { xfail { ! openacc_host_selected } }] == "F" } { xfail "[testname-for-summary] really is XFAILed" } } } ! ... so that we still get an XFAIL visible in the log.
+  print *, "CheCKpOInT2"
+  ! { dg-output ".CheCKpOInT2(\n|\r\n|\r)" { target { openacc_host_selected } } }
 
 !$acc end data
 
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-1-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-1-1.f90
new file mode 100644
index 000000000000..449a6cf6894e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-1-1.f90
@@ -0,0 +1,41 @@
+! { dg-do run }
+! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
+
+! Adapted from 'libgomp.oacc-fortran/deep-copy-6.f90'.
+
+program main
+  use openacc
+  implicit none
+  integer, parameter :: n = 512
+  type mytype
+    integer, allocatable :: a(:)
+  end type mytype
+  type(mytype) :: var
+
+  allocate(var%a(1:n))
+
+  !$acc data create(var)
+
+  !$acc enter data create(var%a)
+
+  if (.not. acc_is_present(var%a)) stop 1
+  if (.not. acc_is_present(var)) stop 2
+
+  !$acc exit data delete(var%a) finalize
+  if (acc_is_present(var%a)) stop 3
+  print *, "CheCKpOInT1"
+  ! { dg-output ".*CheCKpOInT1(\n|\r\n|\r)" }
+  if (.not. acc_is_present(var)) stop 4
+  !TODO { dg-output "STOP 4(\n|\r\n|\r)$" { target { ! openacc_host_selected } } } ! Scan for what we expect in the "XFAILed" case (without actually XFAILing).
+  !TODO { dg-shouldfail "XFAILed" { ! openacc_host_selected } } ! ... instead of 'dg-xfail-run-if' so that 'dg-output' is evaluated at all.
+  !TODO { dg-final { if { [dg-process-target { xfail { ! openacc_host_selected } }] == "F" } { xfail "[testname-for-summary] really is XFAILed" } } } ! ... so that we still get an XFAIL visible in the log.
+  print *, "CheCKpOInT2"
+  ! { dg-output ".CheCKpOInT2(\n|\r\n|\r)" { target { openacc_host_selected } } }
+
+  !$acc end data
+  if (acc_is_present(var%a)) stop 5
+  if (acc_is_present(var)) stop 6
+
+  deallocate(var%a)
+
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-1-2.F90 b/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-1-2.F90
new file mode 100644
index 000000000000..7b206ac20428
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-1-2.F90
@@ -0,0 +1,9 @@
+! { dg-do run }
+! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
+
+/* Nullify the 'finalize' clause, which disturbs reference counting.  */
+#define finalize
+#include "mdc-refcount-1-1-1.f90"
+
+! { dg-output ".*CheCKpOInT1(\n|\r\n|\r)" }
+! { dg-output ".CheCKpOInT2(\n|\r\n|\r)" }
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-2-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-2-1.f90
new file mode 100644
index 000000000000..a7e649d30415
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-2-1.f90
@@ -0,0 +1,43 @@
+! { dg-do run }
+! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
+
+! Adapted from 'libgomp.oacc-fortran/mdc-refcount-1-1-1.f90'.
+
+program main
+  use openacc
+  implicit none
+  integer, parameter :: n = 512
+  type mytype
+    integer, allocatable :: a(:)
+  end type mytype
+  type(mytype) :: var
+
+  allocate(var%a(1:n))
+
+  !$acc data create(var)
+
+  call acc_create(var%a)
+  ! After mapping via runtime API call, separately trigger attach action; see <https://github.com/OpenACC/openacc-spec/issues/301>.
+  !$acc enter data attach(var%a)
+
+  if (.not. acc_is_present(var%a)) stop 1
+  if (.not. acc_is_present(var)) stop 2
+
+  !$acc exit data delete(var%a) finalize
+  if (acc_is_present(var%a)) stop 3
+  print *, "CheCKpOInT1"
+  ! { dg-output ".*CheCKpOInT1(\n|\r\n|\r)" }
+  if (.not. acc_is_present(var)) stop 4
+  !TODO { dg-output "STOP 4(\n|\r\n|\r)$" { target { ! openacc_host_selected } } } ! Scan for what we expect in the "XFAILed" case (without actually XFAILing).
+  !TODO { dg-shouldfail "XFAILed" { ! openacc_host_selected } } ! ... instead of 'dg-xfail-run-if' so that 'dg-output' is evaluated at all.
+  !TODO { dg-final { if { [dg-process-target { xfail { ! openacc_host_selected } }] == "F" } { xfail "[testname-for-summary] really is XFAILed" } } } ! ... so that we still get an XFAIL visible in the log.
+  print *, "CheCKpOInT2"
+  ! { dg-output ".CheCKpOInT2(\n|\r\n|\r)" { target { openacc_host_selected } } }
+
+  !$acc end data
+  if (acc_is_present(var%a)) stop 5
+  if (acc_is_present(var)) stop 6
+
+  deallocate(var%a)
+
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-2-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-2-2.f90
new file mode 100644
index 000000000000..3402fafc7e28
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-2-2.f90
@@ -0,0 +1,43 @@
+! { dg-do run }
+! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
+
+! Copy of 'libgomp.oacc-fortran/mdc-refcount-1-2-1.f90', without 'finalize' clause.
+
+program main
+  use openacc
+  implicit none
+  integer, parameter :: n = 512
+  type mytype
+    integer, allocatable :: a(:)
+  end type mytype
+  type(mytype) :: var
+
+  allocate(var%a(1:n))
+
+  !$acc data create(var)
+
+  call acc_create(var%a)
+  ! After mapping via runtime API call, separately trigger attach action; see <https://github.com/OpenACC/openacc-spec/issues/301>.
+  !$acc enter data attach(var%a)
+
+  if (.not. acc_is_present(var%a)) stop 1
+  if (.not. acc_is_present(var)) stop 2
+
+  !$acc exit data delete(var%a)
+  if (acc_is_present(var%a)) stop 3
+  print *, "CheCKpOInT1"
+  ! { dg-output ".*CheCKpOInT1(\n|\r\n|\r)" }
+  if (.not. acc_is_present(var)) stop 4
+  !TODO { dg-output "STOP 4(\n|\r\n|\r)$" { target { ! openacc_host_selected } } } ! Scan for what we expect in the "XFAILed" case (without actually XFAILing).
+  !TODO { dg-shouldfail "XFAILed" { ! openacc_host_selected } } ! ... instead of 'dg-xfail-run-if' so that 'dg-output' is evaluated at all.
+  !TODO { dg-final { if { [dg-process-target { xfail { ! openacc_host_selected } }] == "F" } { xfail "[testname-for-summary] really is XFAILed" } } } ! ... so that we still get an XFAIL visible in the log.
+  print *, "CheCKpOInT2"
+  ! { dg-output ".CheCKpOInT2(\n|\r\n|\r)" { target { openacc_host_selected } } }
+
+  !$acc end data
+  if (acc_is_present(var%a)) stop 5
+  if (acc_is_present(var)) stop 6
+
+  deallocate(var%a)
+
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-3-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-3-1.f90
new file mode 100644
index 000000000000..7504969d9a56
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-3-1.f90
@@ -0,0 +1,44 @@
+! { dg-do run }
+! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
+
+! Adapted from 'libgomp.oacc-fortran/mdc-refcount-1-2-1.f90'.
+
+program main
+  use openacc
+  implicit none
+  integer, parameter :: n = 512
+  type mytype
+    integer, allocatable :: a(:)
+  end type mytype
+  type(mytype) :: var
+
+  allocate(var%a(1:n))
+
+  !$acc data create(var)
+
+  call acc_create(var%a)
+  ! After mapping via runtime API call, separately trigger attach action; see <https://github.com/OpenACC/openacc-spec/issues/301>.
+  !$acc enter data attach(var%a)
+
+  if (.not. acc_is_present(var%a)) stop 1
+  if (.not. acc_is_present(var)) stop 2
+
+  !$acc exit data detach(var%a)
+  !$acc exit data delete(var%a) finalize
+  if (acc_is_present(var%a)) stop 3
+  print *, "CheCKpOInT1"
+  ! { dg-output ".*CheCKpOInT1(\n|\r\n|\r)" }
+  if (.not. acc_is_present(var)) stop 4
+  !TODO { dg-output "STOP 4(\n|\r\n|\r)$" { target { ! openacc_host_selected } } } ! Scan for what we expect in the "XFAILed" case (without actually XFAILing).
+  !TODO { dg-shouldfail "XFAILed" { ! openacc_host_selected } } ! ... instead of 'dg-xfail-run-if' so that 'dg-output' is evaluated at all.
+  !TODO { dg-final { if { [dg-process-target { xfail { ! openacc_host_selected } }] == "F" } { xfail "[testname-for-summary] really is XFAILed" } } } ! ... so that we still get an XFAIL visible in the log.
+  print *, "CheCKpOInT2"
+  ! { dg-output ".CheCKpOInT2(\n|\r\n|\r)" { target { openacc_host_selected } } }
+
+  !$acc end data
+  if (acc_is_present(var%a)) stop 5
+  if (acc_is_present(var)) stop 6
+
+  deallocate(var%a)
+
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-3-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-3-2.f90
new file mode 100644
index 000000000000..3c4bbda7f665
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-3-2.f90
@@ -0,0 +1,44 @@
+! { dg-do run }
+! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
+
+! Copy of 'libgomp.oacc-fortran/mdc-refcount-1-3-1.f90', without 'finalize' clause.
+
+program main
+  use openacc
+  implicit none
+  integer, parameter :: n = 512
+  type mytype
+    integer, allocatable :: a(:)
+  end type mytype
+  type(mytype) :: var
+
+  allocate(var%a(1:n))
+
+  !$acc data create(var)
+
+  call acc_create(var%a)
+  ! After mapping via runtime API call, separately trigger attach action; see <https://github.com/OpenACC/openacc-spec/issues/301>.
+  !$acc enter data attach(var%a)
+
+  if (.not. acc_is_present(var%a)) stop 1
+  if (.not. acc_is_present(var)) stop 2
+
+  !$acc exit data detach(var%a)
+  print *, "CheCKpOInT1"
+  ! { dg-output ".*CheCKpOInT1(\n|\r\n|\r)" }
+  !$acc exit data delete(var%a)
+  !TODO { dg-output "(\n|\r\n|\r)libgomp: attach count underflow(\n|\r\n|\r)$" { target { ! openacc_host_selected } } } ! Scan for what we expect in the "XFAILed" case (without actually XFAILing).
+  !TODO { dg-shouldfail "XFAILed" { ! openacc_host_selected } } ! ... instead of 'dg-xfail-run-if' so that 'dg-output' is evaluated at all.
+  !TODO { dg-final { if { [dg-process-target { xfail { ! openacc_host_selected } }] == "F" } { xfail "[testname-for-summary] really is XFAILed" } } } ! ... so that we still get an XFAIL visible in the log.
+  print *, "CheCKpOInT2"
+  ! { dg-output ".CheCKpOInT2(\n|\r\n|\r)" { target { openacc_host_selected } } }
+  if (acc_is_present(var%a)) stop 3
+  if (.not. acc_is_present(var)) stop 4
+
+  !$acc end data
+  if (acc_is_present(var%a)) stop 5
+  if (acc_is_present(var)) stop 6
+
+  deallocate(var%a)
+
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-4-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-4-1.f90
new file mode 100644
index 000000000000..fedae0db054b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-4-1.f90
@@ -0,0 +1,44 @@
+! { dg-do run }
+! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
+
+! Adapted from 'libgomp.oacc-fortran/mdc-refcount-1-3-1.f90'.
+
+program main
+  use openacc
+  implicit none
+  integer, parameter :: n = 512
+  type mytype
+    integer, allocatable :: a(:)
+  end type mytype
+  type(mytype) :: var
+
+  allocate(var%a(1:n))
+
+  !$acc data create(var)
+
+  call acc_create(var%a)
+  ! After mapping via runtime API call, separately trigger attach action; see <https://github.com/OpenACC/openacc-spec/issues/301>.
+  !$acc enter data attach(var%a)
+
+  if (.not. acc_is_present(var%a)) stop 1
+  if (.not. acc_is_present(var)) stop 2
+
+  !$acc exit data detach(var%a) finalize
+  print *, "CheCKpOInT1"
+  ! { dg-output ".*CheCKpOInT1(\n|\r\n|\r)" }
+  !$acc exit data delete(var%a)
+  !TODO { dg-output "(\n|\r\n|\r)libgomp: struct not mapped for detach operation(\n|\r\n|\r)$" { target { ! openacc_host_selected } } } ! Scan for what we expect in the "XFAILed" case (without actually XFAILing).
+  !TODO { dg-shouldfail "XFAILed" { ! openacc_host_selected } } ! ... instead of 'dg-xfail-run-if' so that 'dg-output' is evaluated at all.
+  !TODO { dg-final { if { [dg-process-target { xfail { ! openacc_host_selected } }] == "F" } { xfail "[testname-for-summary] really is XFAILed" } } } ! ... so that we still get an XFAIL visible in the log.
+  print *, "CheCKpOInT2"
+  ! { dg-output ".CheCKpOInT2(\n|\r\n|\r)" { target { openacc_host_selected } } }
+  if (acc_is_present(var%a)) stop 3
+  if (.not. acc_is_present(var)) stop 4
+
+  !$acc end data
+  if (acc_is_present(var%a)) stop 5
+  if (acc_is_present(var)) stop 6
+
+  deallocate(var%a)
+
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-4-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-4-2.f90
new file mode 100644
index 000000000000..476cd5c1beea
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/mdc-refcount-1-4-2.f90
@@ -0,0 +1,44 @@
+! { dg-do run }
+! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
+
+! Copy of 'libgomp.oacc-fortran/mdc-refcount-1-4-1.f90', without 'finalize' clause.
+
+program main
+  use openacc
+  implicit none
+  integer, parameter :: n = 512
+  type mytype
+    integer, allocatable :: a(:)
+  end type mytype
+  type(mytype) :: var
+
+  allocate(var%a(1:n))
+
+  !$acc data create(var)
+
+  call acc_create(var%a)
+  ! After mapping via runtime API call, separately trigger attach action; see <https://github.com/OpenACC/openacc-spec/issues/301>.
+  !$acc enter data attach(var%a)
+
+  if (.not. acc_is_present(var%a)) stop 1
+  if (.not. acc_is_present(var)) stop 2
+
+  !$acc exit data detach(var%a)
+  print *, "CheCKpOInT1"
+  ! { dg-output ".*CheCKpOInT1(\n|\r\n|\r)" }
+  !$acc exit data delete(var%a)
+  !TODO { dg-output "(\n|\r\n|\r)libgomp: attach count underflow(\n|\r\n|\r)$" { target { ! openacc_host_selected } } } ! Scan for what we expect in the "XFAILed" case (without actually XFAILing).
+  !TODO { dg-shouldfail "XFAILed" { ! openacc_host_selected } } ! ... instead of 'dg-xfail-run-if' so that 'dg-output' is evaluated at all.
+  !TODO { dg-final { if { [dg-process-target { xfail { ! openacc_host_selected } }] == "F" } { xfail "[testname-for-summary] really is XFAILed" } } } ! ... so that we still get an XFAIL visible in the log.
+  print *, "CheCKpOInT2"
+  ! { dg-output ".CheCKpOInT2(\n|\r\n|\r)" { target { openacc_host_selected } } }
+  if (acc_is_present(var%a)) stop 3
+  if (.not. acc_is_present(var)) stop 4
+
+  !$acc end data
+  if (acc_is_present(var%a)) stop 5
+  if (acc_is_present(var)) stop 6
+
+  deallocate(var%a)
+
+end program main
-- 
2.26.2

