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.