! { 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