https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88447

            Bug ID: 88447
           Summary: Non-contiguous array argument of some class not passed
                    properly to subroutine
           Product: gcc
           Version: 8.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mscfd at gmx dot net
  Target Milestone: ---

Using a non-contiguous argument to a subroutine whose declaration is "class(s),
dimension(:)" gives wrong results. The output looks like that some internal
offset in the array descriptor is computed wrongly. Using type(s) instead of
class(s) fixes the problem. The bug also occurs with the class(*) variant.

module mod

implicit none
private

public p, qi, qr, qv

type, public :: s
   real, dimension(1:3) :: vec
end type s

type, public :: t
   integer :: i
   type(s) :: v
   real :: r
end type t


contains


subroutine p(x)
   class(*), dimension(:), intent(in) :: x
   integer :: i
   select type (x)
   type is (integer)
      write(*,'(a,*(i12))')   'x = ', x
   type is (real)
      write(*,'(a,*(f12.3))') 'x = ', x
   type is (s)
      write(*,'(a,*(3f12.3," |"))') 'x = ', (x(i)%vec, i=1,ubound(x,1))
   end select
end subroutine p


subroutine qi(x)
   integer, dimension(:), intent(in) :: x
   write(*,'(a,*(i12))')   'x = ', x
end subroutine qi

subroutine qr(x)
   real, dimension(:), intent(in) :: x
   write(*,'(a,*(f12.3))') 'x = ', x
end subroutine qr

subroutine qv(x)
   ! with type(s) the bug does not occur
   !type(s), dimension(:), intent(in) :: x
   class(s), dimension(:), intent(in) :: x
   integer :: i
   write(*,'(a,*(3f12.3," |"))') 'x = ', (x(i)%vec, i=1,ubound(x,1))
end subroutine qv

end module mod



program noncontiguous

use mod
implicit none

integer :: k
type(t), dimension(1:4) :: a

do k = 1,4
   a(k)%i = k
   a(k)%r = 10.0 * 2.0*real(k)
   a(k)%v%vec = [real(k)-2.0, real(k)-3.0, real(k)-5.0]
end do

! wrong output for all three calls
call p(a%i)
call p(a%r) 
call p(a%v)

! correct output for the first and second call,
! wrong output for third call (correct if type(s) instead of class(s) is used)
call qi(a%i)
call qr(a%r)
call qv(a%v)

end program noncontiguous

Reply via email to