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

            Bug ID: 128559
           Summary: The fortran library uses bytes strides calculated from
                    the element length instead of the span
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: libfortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mikael at gcc dot gnu.org
  Target Milestone: ---

The macro GFC_DESCRIPTOR_STRIDE_BYTES, used in the fortran library, is defined
as:

   508  #define GFC_DESCRIPTOR_STRIDE_BYTES(desc,i) \
   509    (GFC_DESCRIPTOR_STRIDE(desc,i) * GFC_DESCRIPTOR_SIZE(desc))

where GFC_DESCRIPTOR_STRIDE is defined the obvious way, and GFC_DESCRIPTOR_SIZE
is defined as:

   482  #define GFC_DESCRIPTOR_SIZE(desc) ((desc)->dtype.elem_len)


So basically the stride in bytes is using the element length from the dtype,
but I think it should be using the span instead.  Here is a testcase with
EOSHIFT:

program prog
   implicit none
   integer, parameter :: n = 7
   type :: t1
      integer :: c1, c2
   end type
   type, extends(t1) :: t2
      integer :: c3
   end type
   type(t2), target :: a(n)
   integer :: i
   a = [ (t2(2*i*i+1, 3*i+2, i*i), i=1,n) ]
   call sub(a%t1)
contains
   subroutine sub(x)
      type(t1), pointer, intent(in) :: x(:)
      type(t1) :: expected(n), fill
      integer :: lshift = 3, i
      fill = t1(-1, -2)
      call check_all(eoshift(x, lshift, fill))
   end subroutine
   subroutine check_all(x)
      type(t1), target, intent(in) :: x(:)
      call check(x%c1, [33, 51, 73, 99, -1, -1, -1], 1)
      call check(x%c2, [14, 17, 20, 23, -2, -2, -2], 2)
   end subroutine
   subroutine check(x, y, e)
      integer, target, intent(in) :: x(:), y(:)
      integer, intent(in) :: e
      if (size(x, 1) /= size(y, 1)) error stop e*10+8
      do i = 1, n
         print *, e*10+i, (x(i) == y(i) ? "PASS" : "FAIL"), x(i), y(i)
      end do
      !if (any(x /= y)) error stop e*10+9
   end subroutine
end program

This gives the following output when executed:
          11 FAIL          19          33
          12 FAIL           9          51
          13 FAIL          14          73
          14 FAIL          51          99
          15 PASS          -1          -1
          16 PASS          -1          -1
          17 PASS          -1          -1
          21 FAIL          11          14
          22 FAIL          33          17
          23 FAIL          16          20
          24 FAIL          17          23
          25 PASS          -2          -2
          26 PASS          -2          -2
          27 PASS          -2          -2

If the X argument isn't a pointer but a target instead, a temporary is
generated and all checks PASS.

Reply via email to