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.

Reply via email to