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.