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

            Bug ID: 127612
           Summary: Rank-remapping pointer assignment can incorrectly 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: ---

The assignment of span in a rank-remapping pointer assignment is implemented
as:

 11956                /* Copy the span.  */
 11957                if (VAR_P (rse.expr)
 11958                    && GFC_DECL_PTR_ARRAY_P (rse.expr))
 11959                  span = gfc_conv_descriptor_span_get (rse.expr);
 11960                else
 11961                  {
 11962                    tmp = TREE_TYPE (rse.expr);
 11963                    tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
 11964                    span = fold_convert (gfc_array_index_type, tmp);
 11965                  }
 11966                gfc_conv_descriptor_span_set (&block, desc, span);

This copies the span from the descriptor if the target is a pointer, and
otherwise uses the type size.  This fails to handle the case of non-pointer
polymorphic values.

Here is a testcase:

program prog
   implicit none
   integer, parameter :: n = 5
   type :: t1
      integer :: c1, c2
   end type
   type, extends(t1) :: t2
      integer :: c3
   end type
   class(t1), allocatable, target :: a(:)
   class(t1), pointer :: p0(:), p1(:)
   integer :: i
   a = [t2 :: (t2(7*i+5,3*i+2,i), i=1,n) ]
   p0(1:n) => a
   p1(1:n) => p0
   call sub(a, [ 12, 19, 26, 33, 40 ], [  5,  8, 11, 14, 17 ], 1)
   a = [t2 :: (t2(3*i*i+2,i*i,i), i=1,n) ]
   call sub(a, [  5, 14, 29, 50, 77 ], [  1,  4,  9, 16, 25 ], 2)
contains
   subroutine sub(x, v1, v2, e)
      class(t1), target, intent(in) :: x(:)
      integer, intent(in) :: v1(:), v2(:), e
      class(t1), contiguous, pointer :: q0(:), q1(:)
      call check(a , v1, v2, e*10+1)
      call check(p0, v1, v2, e*10+2)
      call check(p1, v1, v2, e*10+3)
      call check(x , v1, v2, e*10+6)
      q0(1:n) => x
      call check(q0, v1, v2, e*10+7)
      q1(1:n) => q0
      call check(q1, v1, v2, e*10+8)
   end subroutine
   subroutine check(a, v1, v2, e)
      type(t1), target, intent(in) :: a(:)
      integer, intent(in) :: v1(:), v2(:), e
      call compare(a%c1, v1, e*10+1)
      call compare(a%c2, v2, e*10+2)
   end subroutine
   subroutine compare(a, r, e)
      integer, intent(in) :: a(:), r(:)
      integer, intent(in) :: e
      if (size(a, dim=1) /= size(r, dim=1)) error stop e*10+9
      do i = 1, size(a,dim=1)
         print *, e*10+i, (a(i) == r(i) ? "PASS" : "FAIL"), a(i), r(i)
      end do
      !if (any(a%c1 /= [ 12, 19, 26, 33, 40 ])) error stop e*10+1
   end subroutine
end program

When run, it shows the following output:
        1111 PASS          12          12
        1112 PASS          19          19
        1113 PASS          26          26
        1114 PASS          33          33
        1115 PASS          40          40
        1121 PASS           5           5
        1122 PASS           8           8
        1123 PASS          11          11
        1124 PASS          14          14
        1125 PASS          17          17
        1211 PASS          12          12
        1212 FAIL           1          19
        1213 FAIL           8          26
        1214 FAIL          26          33
        1215 FAIL           3          40
        1221 PASS           5           5
        1222 FAIL          19           8
        1223 FAIL           2          11
        1224 FAIL          11          14
        1225 FAIL          33          17
        1311 PASS          12          12
        1312 FAIL           1          19
        1313 FAIL           8          26
        1314 FAIL          26          33
        1315 FAIL           3          40
        1321 PASS           5           5
        1322 FAIL          19           8
        1323 FAIL           2          11
        1324 FAIL          11          14
        1325 FAIL          33          17
        1611 PASS          12          12
        1612 PASS          19          19
        1613 PASS          26          26
        1614 PASS          33          33
        1615 PASS          40          40
        1621 PASS           5           5
        1622 PASS           8           8
        1623 PASS          11          11
        1624 PASS          14          14
        1625 PASS          17          17
        1711 PASS          12          12
        1712 FAIL           1          19
        1713 FAIL           8          26
        1714 FAIL          26          33
        1715 FAIL           3          40
        1721 PASS           5           5
        1722 FAIL          19           8
        1723 FAIL           2          11
        1724 FAIL          11          14
        1725 FAIL          33          17
        1811 PASS          12          12
        1812 FAIL           1          19
        1813 FAIL           8          26
        1814 FAIL          26          33
        1815 FAIL           3          40
        1821 PASS           5           5
        1822 FAIL          19           8
        1823 FAIL           2          11
        1824 FAIL          11          14
        1825 FAIL          33          17
        2111 PASS           5           5
        2112 PASS          14          14
        2113 PASS          29          29
        2114 PASS          50          50
        2115 PASS          77          77
        2121 PASS           1           1
        2122 PASS           4           4
        2123 PASS           9           9
        2124 PASS          16          16
        2125 PASS          25          25
        2211 PASS           5           5
        2212 FAIL           1          14
        2213 FAIL           4          29
        2214 FAIL          29          50
        2215 FAIL           3          77
        2221 PASS           1           1
        2222 FAIL          14           4
        2223 FAIL           2           9
        2224 FAIL           9          16
        2225 FAIL          50          25
        2311 PASS           5           5
        2312 FAIL           1          14
        2313 FAIL           4          29
        2314 FAIL          29          50
        2315 FAIL           3          77
        2321 PASS           1           1
        2322 FAIL          14           4
        2323 FAIL           2           9
        2324 FAIL           9          16
        2325 FAIL          50          25
        2611 PASS           5           5
        2612 PASS          14          14
        2613 PASS          29          29
        2614 PASS          50          50
        2615 PASS          77          77
        2621 PASS           1           1
        2622 PASS           4           4
        2623 PASS           9           9
        2624 PASS          16          16
        2625 PASS          25          25
        2711 PASS           5           5
        2712 FAIL           1          14
        2713 FAIL           4          29
        2714 FAIL          29          50
        2715 FAIL           3          77
        2721 PASS           1           1
        2722 FAIL          14           4
        2723 FAIL           2           9
        2724 FAIL           9          16
        2725 FAIL          50          25
        2811 PASS           5           5
        2812 FAIL           1          14
        2813 FAIL           4          29
        2814 FAIL          29          50
        2815 FAIL           3          77
        2821 PASS           1           1
        2822 FAIL          14           4
        2823 FAIL           2           9
        2824 FAIL           9          16
        2825 FAIL          50          25

The expected output has only PASSes in the second column and equal values in
columns 3 and 4.

Reply via email to