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

            Bug ID: 127613
           Summary: Polymorphic contiguous values not recognized as simply
                    contiguous
           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 following part of the implementation of gfc_is_simply_contiguous doesn't
support polymorphic _data components in the expression subreferences.

  6462    for (ref = expr->ref; ref; ref = ref->next)
  6463      {
  6464        if (ar)
  6465          return false; /* Array shall be last part-ref.  */
  6466  
  6467        if (ref->type == REF_COMPONENT)
  6468          part_ref  = ref;
  6469        else if (ref->type == REF_SUBSTRING)
  6470          return false;
  6471        else if (ref->type == REF_INQUIRY)
  6472          return false;
  6473        else if (ref->u.ar.type != AR_ELEMENT)
  6474          ar = &ref->u.ar;
  6475      }
  6476  
  6477    sym = expr->symtree->n.sym;
  6478    if ((part_ref
  6479         && part_ref->u.c.component
  6480         && !part_ref->u.c.component->attr.contiguous
  6481         && IS_POINTER (part_ref->u.c.component))
  6482        || (!part_ref
  6483            && expr->ts.type != BT_CLASS
  6484            && !sym->attr.contiguous
  6485            && (sym->attr.pointer
  6486                || (sym->as && sym->as->type == AS_ASSUMED_RANK)
  6487                || (sym->as && sym->as->type == AS_ASSUMED_SHAPE))))
  6488      return false;

This incorrectly returns false here for a polymorphic contiguous pointer,
because the part_ref has the pointer attribute, but it is the parent ref that
has the contiguous attribute.

The problem doesn't trigger easily because the _data reference is only created
by a call to gfc_fix_class_refs, so it isn't present during resolution where
all the contiguous rules checking happens.

The following testcase using associate demonstrates it:

program prog
   implicit none
   integer, parameter :: n = 3
   type :: t
      integer :: c
   end type
   type(t), allocatable, target :: x(:,:)
   integer :: i
   x = reshape([ (t(i*i), i=1,n*n) ], [n,n])
   call sub(x)
contains
   subroutine sub(y)
      class(t), contiguous, target  :: y(:,:)
      class(t), contiguous, pointer :: p(:,:)
      class(t), pointer :: q(:)
      associate (a => y)
         q(1:n*n) => a
      end associate
      p => y
      associate (b => p)
         q(1:n*n) => b
      end associate
   end subroutine
end program

The testcase is rejected with the following bogus errors:
> test_contiguous.f90:17:21:
> 
>    17 |          q(1:n*n) => a
>       |                     1
> Error: Rank remapping target must be rank 1 or simply contiguous at (1)
> test_contiguous.f90:21:21:
> 
>    21 |          q(1:n*n) => b
>       |                     1
> Error: Rank remapping target must be rank 1 or simply contiguous at (1)

This shows that the contiguous attribute of y and p is not propagated to the
associate names, a and b respectively.

Reply via email to