|  | ! { dg-do run } | 
|  | ! { dg-require-effective-target offload_device_nonshared_as } */ | 
|  |  | 
|  | module target_test | 
|  | implicit none (type, external) | 
|  | integer, parameter :: N = 40 | 
|  | integer :: sum | 
|  | integer :: var1 = 1 | 
|  | integer :: var2 = 2 | 
|  |  | 
|  | !$omp declare target to(D) | 
|  | integer :: D(N) = 0 | 
|  | contains | 
|  | subroutine enter_data (X) | 
|  | integer :: X(:) | 
|  | !$omp target enter data map(to: var1, var2, X) map(alloc: sum) | 
|  | end subroutine enter_data | 
|  |  | 
|  | subroutine exit_data_0 (D) | 
|  | integer :: D(N) | 
|  | !$omp target exit data map(delete: D) | 
|  | end subroutine exit_data_0 | 
|  |  | 
|  | subroutine exit_data_1 () | 
|  | !$omp target exit data map(from: var1) | 
|  | end subroutine exit_data_1 | 
|  |  | 
|  | subroutine exit_data_2 (X) | 
|  | integer :: X(N) | 
|  | !$omp target exit data map(from: var2) map(release: X, sum) | 
|  | end subroutine exit_data_2 | 
|  |  | 
|  | subroutine exit_data_3 (p, idx) | 
|  | integer :: p(:) | 
|  | integer, value :: idx | 
|  | !$omp target exit data map(from: p(idx)) | 
|  | end subroutine exit_data_3 | 
|  |  | 
|  | subroutine test_nested () | 
|  | integer :: X, Y, Z | 
|  | X = 0 | 
|  | Y = 0 | 
|  | Z = 0 | 
|  |  | 
|  | !$omp target data map(from: X, Y, Z) | 
|  | !$omp target data map(from: X, Y, Z) | 
|  | !$omp target map(from: X, Y, Z) | 
|  | X = 1337 | 
|  | Y = 1337 | 
|  | Z = 1337 | 
|  | !$omp end target | 
|  | if (X /= 0) stop 11 | 
|  | if (Y /= 0) stop 12 | 
|  | if (Z /= 0) stop 13 | 
|  |  | 
|  | !$omp target exit data map(from: X) map(release: Y) | 
|  | if (X /= 0) stop 14 | 
|  | if (Y /= 0) stop 15 | 
|  |  | 
|  | !$omp target exit data map(release: Y) map(delete: Z) | 
|  | if (Y /= 0) stop 16 | 
|  | if (Z /= 0) stop 17 | 
|  | !$omp end target data | 
|  | if (X /= 1337) stop 18 | 
|  | if (Y /= 0) stop 19 | 
|  | if (Z /= 0) stop 20 | 
|  |  | 
|  | !$omp target map(from: X) | 
|  | X = 2448 | 
|  | !$omp end target | 
|  | if (X /= 2448) stop 21 | 
|  | if (Y /= 0) stop 22 | 
|  | if (Z /= 0) stop 23 | 
|  |  | 
|  | X = 4896 | 
|  | !$omp end target data | 
|  | if (X /= 4896) stop 24 | 
|  | if (Y /= 0) stop 25 | 
|  | if (Z /= 0) stop 26 | 
|  | end subroutine test_nested | 
|  | end module target_test | 
|  |  | 
|  | program main | 
|  | use target_test | 
|  | implicit none (type, external) | 
|  |  | 
|  | integer, allocatable :: X(:) | 
|  | integer, pointer, contiguous :: Y(:) | 
|  |  | 
|  |  | 
|  | allocate(X(N), Y(N)) | 
|  | X(10) = 10 | 
|  | Y(20) = 20 | 
|  | call enter_data (X) | 
|  |  | 
|  | call exit_data_0 (D)  ! This should have no effect on D. | 
|  |  | 
|  | !$omp target map(alloc: var1, var2, X) map(to: Y) map(always, from: sum) | 
|  | var1 = var1 + X(10) | 
|  | var2 = var2 + Y(20) | 
|  | sum = var1 + var2 | 
|  | D(sum) = D(sum) + 1 | 
|  | !$omp end target | 
|  |  | 
|  | if (var1 /= 1) stop 1 | 
|  | if (var2 /= 2) stop 2 | 
|  | if (sum /= 33) stop 3 | 
|  |  | 
|  | call exit_data_1 () | 
|  | if (var1 /= 11) stop 4 | 
|  | if (var2 /= 2) stop 5 | 
|  |  | 
|  | ! Increase refcount of already mapped X(1:N). | 
|  | !$omp target enter data map(alloc: X(16:17)) | 
|  |  | 
|  | call exit_data_2 (X) | 
|  | if (var2 /= 22) stop 6 | 
|  |  | 
|  | call exit_data_3 (X, 5) ! Unmap X(1:N). | 
|  |  | 
|  | deallocate (X, Y) | 
|  |  | 
|  | call test_nested () | 
|  | end program main |