| ! 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 non-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 (a, lb0, lb1, ub0, ub1, s0, s1, r) bind (c) |
| use iso_c_binding |
| use mm |
| type(m), target :: a(:,:) |
| 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 |
| |
| call test (aa, 3, 1, 3, 20, 0, 1) ! full slice 0 |
| call test (aa, 1, 8, 10, 8, 1, 0) ! full slice 1 |
| call test (aa, 3, 5, 3, 14, 0, 3) ! partial slice 0 |
| call test (aa, 2, 8, 10, 8, 2, 0) ! partial slice 1 |
| call test (aa, 3, 14, 3, 5, 0, -3) ! backwards slice 0 |
| call test (aa, 10, 8, 2, 8, -2, 0) ! backwards slice 1 |
| |
| contains |
| |
| ! Test function for non-pointer array AA. |
| ! LB, UB, and S describe the section to take. |
| subroutine test (aa, lb0, lb1, ub0, ub1, s0, s1) |
| use mm |
| type(m) :: aa(10,20) |
| integer :: lb0, lb1, ub0, ub1, s0, s1 |
| |
| type(m), pointer :: rr(:) |
| integer :: i0, i1, o0, o1 |
| integer, parameter :: hi0 = 10 |
| integer, parameter :: hi1 = 20 |
| |
| ! Check the bounds actually specify a "slice" rather than a subarray. |
| if (lb0 .ne. ub0 .and. lb1 .ne. ub1) stop 100 |
| |
| ! Call the C function to put a section in rr. |
| ! The C function expects the section bounds to be 1-based. |
| nullify (rr) |
| call ctest (aa, lb0, lb1, ub0, ub1, s0, s1, rr) |
| |
| ! Make sure the original array has not been modified. |
| do i1 = 1, hi1 |
| do i0 = 1, hi0 |
| if (aa(i0,i1)%x .ne. i0) stop 103 |
| if (aa(i0,i1)%y .ne. i1) stop 103 |
| 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) stop 114 |
| if (rr(o1)%y .ne. i1) 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) stop 114 |
| if (rr(o0)%y .ne. lb1) stop 114 |
| o0 = o0 + 1 |
| end do |
| end if |
| end subroutine |
| |
| end program |
| |