! PR 101310 ! { dg-do run } ! { dg-additional-sources "section-3-c.c dump-descriptors.c" } ! { dg-additional-options "-g" } ! ! This program tests basic use of the CFI_section C library function to ! take a slice of a 2-dimensional pointer array. module mm use ISO_C_BINDING type, bind (c) :: m integer(C_INT) :: x, y end type end module program testit use iso_c_binding use mm implicit none interface subroutine ctest (p, lb0, lb1, ub0, ub1, s0, s1, r) bind (c) use iso_c_binding use mm type(m), pointer :: p(:,:) integer(C_INT), value :: lb0, lb1, ub0, ub1, s0, s1 type(m), pointer, intent(out) :: r(:) end subroutine end interface type(m), target :: aa(10, 20) integer :: i0, i1 ! Initialize the test array by numbering its elements. do i1 = 1, 20 do i0 = 1, 10 aa(i0, i1)%x = i0 aa(i0, i1)%y = i1 end do end do ! Zero lower bound call test (aa, 0, 0, 2, 0, 2, 19, 0, 1) ! full slice 0 call test (aa, 0, 0, 0, 7, 9, 7, 1, 0) ! full slice 1 call test (aa, 0, 0, 2, 4, 2, 13, 0, 3) ! partial slice 0 call test (aa, 0, 0, 1, 7, 9, 7, 2, 0) ! partial slice 1 call test (aa, 0, 0, 2, 13, 2, 4, 0, -3) ! backwards slice 0 call test (aa, 0, 0, 9, 7, 1, 7, -2, 0) ! backwards slice 1 ! Lower bound 1 call test (aa, 1, 1, 3, 1, 3, 20, 0, 1) ! full slice 0 call test (aa, 1, 1, 1, 8, 10, 8, 1, 0) ! full slice 1 call test (aa, 1, 1, 3, 5, 3, 14, 0, 3) ! partial slice 0 call test (aa, 1, 1, 2, 8, 10, 8, 2, 0) ! partial slice 1 call test (aa, 1, 1, 3, 14, 3, 5, 0, -3) ! backwards slice 0 call test (aa, 1, 1, 10, 8, 2, 8, -2, 0) ! backwards slice 1 ! Some other lower bound call test (aa, 2, 3, 4, 3, 4, 22, 0, 1) ! full slice 0 call test (aa, 2, 3, 2, 10, 11, 10, 1, 0) ! full slice 1 call test (aa, 2, 3, 4, 7, 4, 16, 0, 3) ! partial slice 0 call test (aa, 2, 3, 3, 10, 11, 10, 2, 0) ! partial slice 1 call test (aa, 2, 3, 4, 16, 4, 7, 0, -3) ! backwards slice 0 call test (aa, 2, 3, 11, 10, 3, 10, -2, 0) ! backwards slice 1 contains subroutine test (aa, lo0, lo1, lb0, lb1, ub0, ub1, s0, s1) use mm type(m), target :: aa(10,20) integer :: lo0, lo1, lb0, lb1, ub0, ub1, s0, s1 type(m), pointer :: pp(:,:), rr(:) integer :: i0, i1, o0, o1 integer :: hi0, hi1 hi0 = lo0 + 10 - 1 hi1 = lo1 + 20 - 1 ! Check the bounds actually specify a "slice" rather than a subarray. if (lb0 .ne. ub0 .and. lb1 .ne. ub1) stop 100 pp(lo0:,lo1:) => aa if (lbound (pp, 1) .ne. lo0) stop 121 if (lbound (pp, 2) .ne. lo1) stop 121 if (ubound (pp, 1) .ne. hi0) stop 122 if (ubound (pp, 2) .ne. hi1) stop 122 nullify (rr) call ctest (pp, lb0, lb1, ub0, ub1, s0, s1, rr) ! Make sure the input pointer array has not been modified. if (lbound (pp, 1) .ne. lo0) stop 131 if (ubound (pp, 1) .ne. hi0) stop 132 if (lbound (pp, 2) .ne. lo1) stop 133 if (ubound (pp, 2) .ne. hi1) stop 134 do i1 = lo1, hi1 do i0 = lo0, hi0 if (pp(i0,i1)%x .ne. i0 - lo0 + 1) stop 135 if (pp(i0,i1)%y .ne. i1 - lo1 + 1) stop 136 end do end do ! Make sure the output array has the expected bounds and elements. if (.not. associated (rr)) stop 111 if (lbound (rr, 1) .ne. 1) stop 112 if (ub0 .eq. lb0) then if (ubound (rr, 1) .ne. (ub1 - lb1)/s1 + 1) stop 113 o1 = 1 do i1 = lb1, ub1, s1 if (rr(o1)%x .ne. lb0 - lo0 + 1) stop 114 if (rr(o1)%y .ne. i1 - lo1 + 1) stop 114 o1 = o1 + 1 end do else if (ubound (rr, 1) .ne. (ub0 - lb0)/s0 + 1) stop 113 o0 = 1 do i0 = lb0, ub0, s0 if (rr(o0)%x .ne. i0 - lo0 + 1) stop 114 if (rr(o0)%y .ne. lb1 - lo1 + 1) stop 114 o0 = o0 + 1 end do end if end subroutine end program