blob: 0cf3b2cb88c355aeb1da23c54cf1b75cf3a6fe8d [file] [log] [blame]
! { dg-do run { target c99_runtime } }
! { dg-additional-sources ISO_Fortran_binding_1.c }
!
! Test F2008 18.5: ISO_Fortran_binding.h functions.
!
USE, INTRINSIC :: ISO_C_BINDING
TYPE, BIND(C) :: T
REAL(C_DOUBLE) :: X
complex(C_DOUBLE_COMPLEX) :: Y
END TYPE
type :: mytype
integer :: i
integer :: j
end type
INTERFACE
FUNCTION elemental_mult(a, b, c) BIND(C, NAME="elemental_mult_c") RESULT(err)
USE, INTRINSIC :: ISO_C_BINDING
INTEGER(C_INT) :: err
type(*), DIMENSION(..) :: a, b, c
END FUNCTION elemental_mult
FUNCTION c_deallocate(a) BIND(C, NAME="deallocate_c") RESULT(err)
USE, INTRINSIC :: ISO_C_BINDING
INTEGER(C_INT) :: err
INTEGER(C_INT), DIMENSION(..), allocatable :: a
END FUNCTION c_deallocate
FUNCTION c_allocate(a, lower, upper) BIND(C, NAME="allocate_c") RESULT(err)
USE, INTRINSIC :: ISO_C_BINDING
INTEGER(C_INT) :: err
INTEGER(C_INT), DIMENSION(..), allocatable :: a
integer(C_INTPTR_T), DIMENSION(15) :: lower, upper
END FUNCTION c_allocate
FUNCTION c_establish(a) BIND(C, NAME="establish_c") RESULT(err)
USE, INTRINSIC :: ISO_C_BINDING
import
INTEGER(C_INT) :: err
type (T), pointer, DIMENSION(..), intent(out) :: a
END FUNCTION c_establish
FUNCTION c_contiguous(a) BIND(C, NAME="contiguous_c") RESULT(err)
USE, INTRINSIC :: ISO_C_BINDING
INTEGER(C_INT) :: err
type(*), DIMENSION(..) :: a
END FUNCTION c_contiguous
FUNCTION c_section(std_case, a, lower, strides) BIND(C, NAME="section_c") RESULT(ans)
USE, INTRINSIC :: ISO_C_BINDING
real(C_FLOAT) :: ans
INTEGER(C_INT) :: std_case
INTEGER(C_INT), dimension(15) :: lower
INTEGER(C_INT), dimension(15) :: strides
type(*), DIMENSION(..) :: a
END FUNCTION c_section
FUNCTION c_select_part(a) BIND(C, NAME="select_part_c") RESULT(ans)
USE, INTRINSIC :: ISO_C_BINDING
real(C_DOUBLE) :: ans
type(*), DIMENSION(..) :: a
END FUNCTION c_select_part
FUNCTION c_setpointer(a, lbounds) BIND(C, NAME="setpointer_c") RESULT(err)
USE, INTRINSIC :: ISO_C_BINDING
INTEGER(C_INT) :: err
INTEGER(C_INT), dimension(2) :: lbounds
INTEGER(C_INT), DIMENSION(..), pointer :: a
END FUNCTION c_setpointer
FUNCTION c_assumed_size(a) BIND(C, NAME="assumed_size_c") RESULT(err)
USE, INTRINSIC :: ISO_C_BINDING
INTEGER(C_INT) :: err
type(*), DIMENSION(..) :: a
END FUNCTION c_assumed_size
END INTERFACE
integer, dimension(:,:), allocatable :: x, y, z
integer, dimension(2,2) :: a, b, c
integer, dimension(4,4) :: d
integer :: i = 42, j, k
integer(C_INTPTR_T), dimension(15) :: lower, upper
real, dimension(10,10) :: arg
type (mytype), dimension(2,2) :: der
allocate (x, source = reshape ([4,3,2,1], [2,2]))
allocate (y, source = reshape ([2,3,4,5], [2,2]))
allocate (z, source = reshape ([0,0,0,0], [2,2]))
call test_CFI_address
call test_CFI_deallocate
call test_CFI_allocate
call test_CFI_establish
call test_CFI_contiguous (a)
call test_CFI_section (arg)
call test_CFI_select_part
call test_CFI_setpointer
call test_assumed_size (a)
contains
subroutine test_CFI_address
! Basic test that CFI_desc_t can be passed and that CFI_address works
if (elemental_mult (z, x, y) .ne. 0) stop 1
if (any (z .ne. reshape ([8,9,8,5], [2,2]))) stop 2
a = reshape ([4,3,2,1], [2,2])
b = reshape ([2,3,4,5], [2,2])
c = 0
! Verify that components of arrays of derived types are OK.
der%j = a
! Check that non-pointer/non-allocatable arguments are OK
if (elemental_mult (c, der%j, b) .ne. 0) stop 3
if (any (c .ne. reshape ([8,9,8,5], [2,2]))) stop 4
! Check array sections
d = 0
d(4:2:-2, 1:3:2) = b
if (elemental_mult (c, a, d(4:2:-2, 1:3:2)) .ne. 0) stop 5
if (any (c .ne. reshape ([8,9,8,5], [2,2]))) stop 6
! If a scalar result is passed to 'elemental_mult' it is returned
! as the function result and then zeroed. This tests that scalars
! are correctly converted to CF_desc_t.
if ((elemental_mult (i, a, b) .ne. 42) &
.or. (i .ne. 0)) stop 7
deallocate (y,z)
end subroutine test_CFI_address
subroutine test_CFI_deallocate
! Test CFI_deallocate.
if (c_deallocate (x) .ne. 0) stop 8
if (allocated (x)) stop 9
end subroutine test_CFI_deallocate
subroutine test_CFI_allocate
! Test CFI_allocate.
lower(1:2) = [2,2]
upper(1:2) = [10,10]
if (c_allocate (x, lower, upper) .ne. 0) stop 10
if (.not.allocated (x)) stop 11
if (any (lbound (x) .ne. lower(1:2))) stop 12
if (any (ubound (x) .ne. upper(1:2))) stop 13
! Elements are filled by 'c_allocate' with the product of the fortran indices
do j = lower(1) , upper(1)
do k = lower(2) , upper(2)
x(j,k) = x(j,k) - j * k
end do
end do
if (any (x .ne. 0)) stop 14
deallocate (x)
end subroutine test_CFI_allocate
subroutine test_CFI_establish
! Test CFI_establish.
type(T), pointer :: case2(:) => null()
if (c_establish(case2) .ne. 0) stop 14
if (ubound(case2, 1) .ne. 9) stop 15
if (.not.associated(case2)) stop 16
if (sizeof(case2) .ne. 240) stop 17
if (int (sum (case2%x)) .ne. 55) stop 18
if (int (sum (imag (case2%y))) .ne. 110) stop 19
deallocate (case2)
end subroutine test_CFI_establish
subroutine test_CFI_contiguous (arg)
integer, dimension (2,*) :: arg
character(4), dimension(2) :: chr
! These are contiguous
if (c_contiguous (arg) .ne. 1) stop 20
if (.not.allocated (x)) allocate (x(2, 2))
if (c_contiguous (x) .ne. 1) stop 22
deallocate (x)
if (c_contiguous (chr) .ne. 1) stop 23
! These are not contiguous
if (c_contiguous (der%i) .eq. 1) stop 24
if (c_contiguous (arg(1:1,1:2)) .eq. 1) stop 25
if (c_contiguous (d(4:2:-2, 1:3:2)) .eq. 1) stop 26
if (c_contiguous (chr(:)(2:3)) .eq. 1) stop 27
end subroutine test_CFI_contiguous
subroutine test_CFI_section (arg)
real, dimension (100) :: a
real, dimension (10,*) :: arg
integer, dimension(15) :: lower, strides
integer :: i
! Case (i) from F2018:18.5.5.7.
a = [(real(i), i = 1, 100)]
lower(1) = 10
strides(1) = 5
! Remember, 'a' being non pointer, non-allocatable, the C descriptor
! lbounds are set to zero.
if (int (sum(a(lower(1)+1::strides(1))) &
- c_section(1, a, lower, strides)) .ne. 0) stop 28
! Case (ii) from F2018:18.5.5.7.
arg(:,1:10) = reshape ([(real(i), i = 1, 100)], [10,10])
lower(1) = 1
lower(2) = 5
strides(1) = 1
strides(2) = 0
if (int (sum(arg(:,5)) &
- c_section (2, arg, lower, strides)) .ne. 0) stop 29
end subroutine test_CFI_section
subroutine test_CFI_select_part
! Test the example from F2018:18.5.5.8.
! Modify to take rank 2 and sum the section type_t(5, :)%y%im
! Note that sum_z_5 = sum (type_t(5, :)%y%im) is broken on Darwin.
!
type (t), dimension(10, 10) :: type_t
real(kind(type_t%x)) :: v, sum_z_5 = 0.0
complex(kind(type_t%y)) :: z
! Set the array 'type_t'.
do j = 1, 10
do k = 1, 10
v = dble (j * k)
z = cmplx (2 * v, 3 * v)
type_t(j, k) = t (v, z)
if (j .eq. 5) sum_z_5 = sum_z_5 + imag (z)
end do
end do
! Now do the test.
if (int (c_select_part (type_t) - sum_z_5) .ne. 0) stop 30
end subroutine test_CFI_select_part
subroutine test_CFI_setpointer
! Test the example from F2018:18.5.5.9.
integer, dimension(:,:), pointer :: ptr => NULL ()
integer, dimension(2,2), target :: tgt
integer, dimension(2) :: lbounds = [-1, -2]
! The C-function resets the lbounds
ptr(1:, 1:) => tgt
if (c_setpointer (ptr, lbounds) .ne. 0) stop 31
if (any (lbound(ptr) .ne. lbounds)) stop 32
end subroutine test_CFI_setpointer
subroutine test_assumed_size (arg)
integer, dimension(2,*) :: arg
! The C-function checks contiguousness and that extent[1] == -1.
if (c_assumed_size (arg) .ne. 0) stop 33
end subroutine
end