https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127448
Bug ID: 127448
Summary: Array pointer assignment doesn't correctly set the
span
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: fortran
Assignee: unassigned at gcc dot gnu.org
Reporter: mikael at gcc dot gnu.org
Target Milestone: ---
In an array pointer to pointer assignment, the span is set from the vtype.
This means the right hand side is assumed to be contiguous, which is not always
the case.
Testcase, testing various pointer assignments:
program prog
implicit none
integer, parameter :: k = 2
integer, parameter :: n = 5
type :: t1
integer(kind=k) :: c1, c2
end type
type, extends(t1) :: t2
integer(kind=k) :: c3
end type
type(t2), target :: x(n)
class(t1), pointer :: y1(:), z1(:)
class(t2), pointer :: y2(:)
type(t1), pointer :: p1(:), q1(:)
integer :: i
x = [ (t2(i*i, 2*i*i+1, i), i=1,n) ]
y2 => x
y1 => x
call check_t1(y1, 12)
z1 => y2
call check_t1(z1, 13)
z1 => y1
call check_t1(z1, 14)
call check_t1(x%t1, 21)
call check_t1(y2%t1, 22)
y1 => x%t1
call check_t1(y1, 23)
z1 => y2%t1
call check_t1(z1, 24)
z1 => y1
call check_t1(z1, 25)
p1 => x%t1
call check_t1(p1, 41)
p1 => y2%t1
call check_t1(p1, 42)
p1 => y1
call check_t1(p1, 43)
q1 => p1
call check_t1(q1, 44)
contains
subroutine check_t1(arg, f)
type(t1), intent(in) :: arg(:)
integer, intent(in) :: f
call check_int(arg%c1, [1, 4, 9, 16, 25], f*10+1)
call check_int(arg%c2, [3, 9, 19, 33, 51], f*10+2)
end subroutine
subroutine check_int(arg, e, f)
integer(kind=k), intent(in) :: arg(:)
integer, intent(in) :: e(:), f
integer :: i
if (size(arg, 1) /= size(e, 1)) error stop 10*f
do i=1,size(arg)
print *, f*10+i, (arg(i) == e(i) ? "PASS" : "FAIL"), arg(i), e(i)
end do
!if (any(arg /= e)) error stop 10*f + findloc(arg /= e, .true., 1)
end subroutine
end program
This gives as output:
1211 PASS 1 1
1212 PASS 4 4
1213 PASS 9 9
1214 PASS 16 16
1215 PASS 25 25
1221 PASS 3 3
1222 PASS 9 9
1223 PASS 19 19
1224 PASS 33 33
1225 PASS 51 51
1311 PASS 1 1
1312 PASS 4 4
1313 PASS 9 9
1314 PASS 16 16
1315 PASS 25 25
1321 PASS 3 3
1322 PASS 9 9
1323 PASS 19 19
1324 PASS 33 33
1325 PASS 51 51
1411 PASS 1 1
1412 PASS 4 4
1413 PASS 9 9
1414 PASS 16 16
1415 PASS 25 25
1421 PASS 3 3
1422 PASS 9 9
1423 PASS 19 19
1424 PASS 33 33
1425 PASS 51 51
2111 PASS 1 1
2112 PASS 4 4
2113 PASS 9 9
2114 PASS 16 16
2115 PASS 25 25
2121 PASS 3 3
2122 PASS 9 9
2123 PASS 19 19
2124 PASS 33 33
2125 PASS 51 51
2211 PASS 1 1
2212 PASS 4 4
2213 PASS 9 9
2214 PASS 16 16
2215 PASS 25 25
2221 PASS 3 3
2222 PASS 9 9
2223 PASS 19 19
2224 PASS 33 33
2225 PASS 51 51
2311 PASS 1 1
2312 FAIL 1 4
2313 PASS 9 9
2314 FAIL 9 16
2315 FAIL 3 25
2321 PASS 3 3
2322 FAIL 4 9
2323 FAIL 2 19
2324 FAIL 19 33
2325 FAIL 16 51
2411 PASS 1 1
2412 FAIL 1 4
2413 PASS 9 9
2414 FAIL 9 16
2415 FAIL 3 25
2421 PASS 3 3
2422 FAIL 4 9
2423 FAIL 2 19
2424 FAIL 19 33
2425 FAIL 16 51
2511 PASS 1 1
2512 FAIL 1 4
2513 PASS 9 9
2514 FAIL 9 16
2515 FAIL 3 25
2521 PASS 3 3
2522 FAIL 4 9
2523 FAIL 2 19
2524 FAIL 19 33
2525 FAIL 16 51
4111 PASS 1 1
4112 PASS 4 4
4113 PASS 9 9
4114 PASS 16 16
4115 PASS 25 25
4121 PASS 3 3
4122 PASS 9 9
4123 PASS 19 19
4124 PASS 33 33
4125 PASS 51 51
4211 PASS 1 1
4212 PASS 4 4
4213 PASS 9 9
4214 PASS 16 16
4215 PASS 25 25
4221 PASS 3 3
4222 PASS 9 9
4223 PASS 19 19
4224 PASS 33 33
4225 PASS 51 51
4311 PASS 1 1
4312 FAIL 1 4
4313 PASS 9 9
4314 FAIL 9 16
4315 FAIL 3 25
4321 PASS 3 3
4322 FAIL 4 9
4323 FAIL 2 19
4324 FAIL 19 33
4325 FAIL 16 51
4411 PASS 1 1
4412 FAIL 1 4
4413 PASS 9 9
4414 FAIL 9 16
4415 FAIL 3 25
4421 PASS 3 3
4422 FAIL 4 9
4423 FAIL 2 19
4424 FAIL 19 33
4425 FAIL 16 51
The expected output is to have PASS in all lines and the same values in columns
3 and 4.
Here is the analysis for the 25* FAILs.
The code for the z1 => y1 pointer assignment shows in the dump as:
z1._vptr = y1._vptr;
z1._data = y1._data;
z1._data.data = NON_LVALUE_EXPR <y1._data.data>;
z1._data.span = y1._vptr->_size;
The explicit data assignment is redundant, but harmless.
The explicit span assignment is wrong and should be removed.
Failures 43* and 44* are similar to 25*.
Failures 23* and 24* need more analysis.