blob: 424eb080fd1a0a38652e043277719ea4199e4ed1 [file] [log] [blame]
! { dg-do run }
! { dg-additional-options "-fdump-tree-original" }
!
! PR fortran/97592 - fix argument passing to CONTIGUOUS,TARGET dummy
!
! { dg-final { scan-tree-dump-times "_gfortran_internal_pack \\(&b_2d" 1 "original" } }
! { dg-final { scan-tree-dump-times "_gfortran_internal_pack \\(&p1" 3 "original" } }
!
! N.B.: there is no reliable count of _gfortran_internal_pack on temporaries parm.*
program pr97592
implicit none
integer :: i, k
integer, target :: a(10)
integer, pointer :: p1(:), p2(:), tgt(:), expect(:)
integer, pointer, contiguous :: cp(:)
integer, allocatable, target :: b(:)
!----------------------
! Code from original PR
!----------------------
call RemappingTest ()
!---------------------
! Additional 1-d tests
!---------------------
a = [(i, i=1,size(a))]
b = a
! Set p1 to an actually contiguous pointer
p1(13:) => a(3::2)
print *, lbound (p1), ubound (p1), is_contiguous (p1)
! non-contiguous pointer actual argument
expect => p1
call chk_cont (p1)
expect => p1
call chk_tgt_cont (p1)
expect => p1
call chk_ptr (p1, p2)
if (any (p2 /= p1)) stop 1
expect => p1
call chk_tgt (p1, p2)
if (any (p2 /= p1)) stop 2
! non-contiguous target actual argument
expect => b(3::2)
call chk_tgt_cont (b(3::2))
expect => b(3::2)
call chk_tgt (b(3::2), p2)
if (any (p2 /= p1)) stop 3
expect => b(3::2)
call chk_ptr (b(3::2), p2)
if (any (p2 /= p1)) stop 4
! Set p1 to an actually contiguous pointer
cp(17:) => a(3:9:1)
p1 => cp
print *, lbound (cp), ubound (cp), is_contiguous (cp)
print *, lbound (p1), ubound (p1), is_contiguous (p1)
expect => p1
call chk_tgt (p1, p2)
if (any (p2 /= cp)) stop 31
expect => cp
call chk_tgt (cp, p2)
if (any (p2 /= cp)) stop 32
expect => cp
call chk_tgt_cont (cp, p2)
if (any (p2 /= cp)) stop 33
expect => cp
call chk_tgt_expl (cp, p2, size (cp))
if (any (p2 /= cp)) stop 34
! See F2018:15.5.2.4 and F2018:C.10.4
expect => p1
call chk_tgt_cont (p1, p2)
! print *, p2
if (any (p2 /= cp)) stop 35
expect => p1
call chk_tgt_expl (p1, p2, size (p1))
if (any (p2 /= cp)) stop 36
expect => cp
call chk_ptr_cont (cp, p2)
if (any (p2 /= cp)) stop 37
! Pass array section which is actually contigous
k = 1
expect => cp(::k)
call chk_ptr (cp(::k), p2)
if (any (p2 /= cp(::k))) stop 38
expect => p1(::k)
call chk_tgt_cont (p1(::k), p2)
if (any (p2 /= p1(::k))) stop 39
expect => p1(::k)
call chk_tgt (p1(::k), p2)
if (any (p2 /= p1(::k))) stop 40
expect => p1(::k)
call chk_tgt_expl (p1(::k), p2, size (p1(::k)))
if (any (p2 /= p1(::k))) stop 41
expect => b(3::k)
call chk_tgt_cont (b(3::k), p2)
if (any (p2 /= b(3::k))) stop 42
expect => b(3::k)
call chk_tgt (b(3::k), p2)
if (any (p2 /= b(3::k))) stop 43
expect => b(3::k)
call chk_tgt_expl (b(3::k), p2, size (b(3::k)))
if (any (p2 /= b(3::k))) stop 44
if (any (a /= [(i, i=1,size(a))])) stop 66
if (any (a /= b)) stop 77
deallocate (b)
contains
! Contiguous pointer dummy
subroutine chk_ptr_cont (x, y)
integer, contiguous, pointer, intent(in) :: x(:)
integer, pointer, optional :: y(:)
print *, lbound (x), ubound (x)
if (present (y)) y => x(:)
if (associated (expect)) then
if (size (x) /= size (expect)) stop 10
if (any (x /= expect)) stop 11
if (lbound(expect,1) /= 1 .and. &
lbound(expect,1) /= lbound (x,1)) stop 20
end if
end
! Pointer dummy
subroutine chk_ptr (x, y)
integer, pointer, intent(in) :: x(:)
integer, pointer, optional :: y(:)
print *, lbound (x), ubound (x)
if (present (y)) y => x(:)
if (associated (expect)) then
if (size (x) /= size (expect)) stop 12
if (any (x /= expect)) stop 13
if (lbound(expect,1) /= 1 .and. &
lbound(expect,1) /= lbound (x,1)) stop 22
end if
end
! Dummy with target attribute
subroutine chk_tgt_cont (x, y)
integer, contiguous, target, intent(in) :: x(:)
integer, pointer, optional :: y(:)
if (present (y)) y => x(:)
if (associated (expect)) then
if (size (x) /= size (expect)) stop 14
if (any (x /= expect)) stop 15
end if
end
subroutine chk_tgt (x, y)
integer, target, intent(in) :: x(:)
integer, pointer, optional :: y(:)
if (present (y)) y => x(:)
if (associated (expect)) then
if (size (x) /= size (expect)) stop 16
if (any (x /= expect)) stop 17
end if
end
! Explicit-shape dummy with target attribute
subroutine chk_tgt_expl (x, y, n)
integer, intent(in) :: n
integer, target, intent(in) :: x(n)
integer, pointer, optional :: y(:)
if (present (y)) y => x(:)
if (associated (expect)) then
if (size (x) /= size (expect)) stop 18
if (any (x /= expect)) stop 19
end if
end
! Dummy without pointer or target attribute
subroutine chk_cont (x)
integer, contiguous, intent(in) :: x(:)
if (associated (expect)) then
if (size (x) /= size (expect)) stop 23
if (any (x /= expect)) stop 24
end if
end
!------------------------------------------------------------------------
subroutine RemappingTest ()
real, pointer :: B_2D(:,:)
real, pointer :: B_3D(:,:,:) => NULL()
integer, parameter :: n1=4, n2=4, n3=3
!-- Prepare B_2D
allocate (B_2D(n1*n2, n3))
B_2D = - huge (1.0)
if (.not. is_contiguous (B_2D)) stop 101
!-- Point B_3D to Storage
call SetPointer (B_2D, n1, n2, n3, B_3D)
!print *,"is_contiguous (B_3D) =", is_contiguous (B_3D)
if (.not. is_contiguous (B_3D)) stop 102
!-- Set B_3D
B_3D = 2.0
!-- See if the result is reflected in Storage
if (any (B_2D /= 2.0)) then
print *, "B_2D = ", B_2D !-- expect 2.0 for all elements
stop 103
end if
print *,"RemappingTest passed"
end
subroutine SetPointer (C_2D, n1, n2, n3, C_3D)
integer, intent(in) :: n1, n2, n3
real, target, contiguous :: C_2D(:,:)
real, pointer :: C_3D(:,:,:)
intent(in) :: C_2D
C_3D(1:n1,1:n2,1:n3) => C_2D
end
end