blob: f3b9ba4d352f9fd1e76e11969fa9587278f32280 [file] [log] [blame]
! { dg-do run }
!
! PR fortran/37336
!
! Check the scalarizer/array packing with strides
! in the finalization wrapper
!
module m
implicit none
type t1
integer :: i = 1
contains
final :: fini_elem
end type t1
type, extends(t1) :: t1e
integer :: j = 11
contains
final :: fini_elem2
end type t1e
type t2
integer :: i = 2
contains
final :: fini_shape
end type t2
type, extends(t2) :: t2e
integer :: j = 22
contains
final :: fini_shape2
end type t2e
type t3
integer :: i = 3
contains
final :: fini_explicit
end type t3
type, extends(t3) :: t3e
integer :: j = 33
contains
final :: fini_explicit2
end type t3e
integer :: cnt1, cnt1e, cnt2, cnt2e, cnt3, cnt3e
contains
impure elemental subroutine fini_elem(x)
type(t1), intent(inout) :: x
integer :: i, j, i2, j2
if (cnt1e /= 5*4) STOP 1
j = mod (cnt1,5)+1
i = cnt1/5 + 1
i2 = (i-1)*3 + 1
j2 = (j-1)*2 + 1
if (x%i /= j2 + 100*i2) STOP 2
x%i = x%i * (-13)
cnt1 = cnt1 + 1
end subroutine fini_elem
impure elemental subroutine fini_elem2(x)
type(t1e), intent(inout) :: x
integer :: i, j, i2, j2
j = mod (cnt1e,5)+1
i = cnt1e/5 + 1
i2 = (i-1)*3 + 1
j2 = (j-1)*2 + 1
if (x%i /= j2 + 100*i2) STOP 3
if (x%j /= (j2 + 100*i2)*100) STOP 4
x%j = x%j * (-13)
cnt1e = cnt1e + 1
end subroutine fini_elem2
subroutine fini_shape(x)
type(t2) :: x(:,:)
if (cnt2e /= 1 .or. cnt2 /= 0) STOP 5
call check_var_sec(x%i, 1)
x%i = x%i * (-13)
cnt2 = cnt2 + 1
end subroutine fini_shape
subroutine fini_shape2(x)
type(t2e) :: x(:,:)
call check_var_sec(x%i, 1)
call check_var_sec(x%j, 100)
x%j = x%j * (-13)
cnt2e = cnt2e + 1
end subroutine fini_shape2
subroutine fini_explicit(x)
type(t3) :: x(5,4)
if (cnt3e /= 1 .or. cnt3 /= 0) STOP 6
call check_var_sec(x%i, 1)
x%i = x%i * (-13)
cnt3 = cnt3 + 1
end subroutine fini_explicit
subroutine fini_explicit2(x)
type(t3e) :: x(5,4)
call check_var_sec(x%i, 1)
call check_var_sec(x%j, 100)
x%j = x%j * (-13)
cnt3e = cnt3e + 1
end subroutine fini_explicit2
subroutine fin_test_1(x)
class(t1), intent(out) :: x(5,4)
end subroutine fin_test_1
subroutine fin_test_2(x)
class(t2), intent(out) :: x(:,:)
end subroutine fin_test_2
subroutine fin_test_3(x)
class(t3), intent(out) :: x(:,:)
if (any (shape(x) /= [5,4])) STOP 7
end subroutine fin_test_3
subroutine check_var_sec(x, factor)
integer :: x(:,:)
integer, value :: factor
integer :: i, j, i2, j2
do i = 1, 4
i2 = (i-1)*3 + 1
do j = 1, 5
j2 = (j-1)*2 + 1
if (x(j,i) /= (j2 + 100*i2)*factor) STOP 8
end do
end do
end subroutine check_var_sec
end module m
program test
use m
implicit none
class(t1), allocatable :: x(:,:)
class(t2), allocatable :: y(:,:)
class(t3), allocatable :: z(:,:)
integer :: i, j
cnt1 = 0; cnt1e = 0; cnt2 = 0; cnt2e = 0; cnt3 = 0; cnt3e = 0
allocate (t1e :: x(10,10))
allocate (t2e :: y(10,10))
allocate (t3e :: z(10,10))
select type(x)
type is (t1e)
do i = 1, 10
do j = 1, 10
x(j,i)%i = j + 100*i
x(j,i)%j = (j + 100*i)*100
end do
end do
end select
select type(y)
type is (t2e)
do i = 1, 10
do j = 1, 10
y(j,i)%i = j + 100*i
y(j,i)%j = (j + 100*i)*100
end do
end do
end select
select type(z)
type is (t3e)
do i = 1, 10
do j = 1, 10
z(j,i)%i = j + 100*i
z(j,i)%j = (j + 100*i)*100
end do
end do
end select
if (cnt1 + cnt1e + cnt2 + cnt2e + cnt3 + cnt3e /= 0) STOP 9
call fin_test_1(x(::2,::3))
if (cnt1 /= 5*4) STOP 10
if (cnt1e /= 5*4) STOP 11
cnt1 = 0; cnt1e = 0
if (cnt2 + cnt2e + cnt3 + cnt3e /= 0) STOP 12
call fin_test_2(y(::2,::3))
if (cnt2 /= 1) STOP 13
if (cnt2e /= 1) STOP 14
cnt2 = 0; cnt2e = 0
if (cnt1 + cnt1e + cnt3 + cnt3e /= 0) STOP 15
call fin_test_3(z(::2,::3))
if (cnt3 /= 1) STOP 16
if (cnt3e /= 1) STOP 17
cnt3 = 0; cnt3e = 0
if (cnt1 + cnt1e + cnt2 + cnt2e /= 0) STOP 18
select type(x)
type is (t1e)
call check_val(x%i, 1, 1)
call check_val(x%j, 100, 11)
end select
select type(y)
type is (t2e)
call check_val(y%i, 1, 2)
call check_val(y%j, 100, 22)
end select
select type(z)
type is (t3e)
call check_val(z%i, 1, 3)
call check_val(z%j, 100, 33)
end select
contains
subroutine check_val(x, factor, val)
integer :: x(:,:)
integer, value :: factor, val
integer :: i, j
do i = 1, 10
do j = 1, 10
if (mod (j-1, 2) == 0 .and. mod (i-1, 3) == 0) then
if (x(j,i) /= val) STOP 19
else
if (x(j,i) /= (j + 100*i)*factor) STOP 20
end if
end do
end do
end subroutine check_val
end program test