https://gcc.gnu.org/g:0aff6f2c1b145e6d35b8ece3da4a7e32dfc74719

commit r17-4884-g0aff6f2c1b145e6d35b8ece3da4a7e32dfc74719
Author: Mikael Morin <[email protected]>
Date:   Mon Oct 5 11:31:33 2026 +0200

    fortran: Fix simply contiguous property for associate subrefs [PR127701]
    
    In the function implementing the simply contiguous property, fix the
    conditions governing the forwarding of the query from an associate name to
    its target.
    
    The query was forwarded to the associate target for any associate name
    reference that was a full array, which included the case of a full array
    component.  But a component may have different contiguous properties from
    the variable it's part of.  Supplement the check guarding the forwarding
    with an additional condition that the subreference walk before saw no
    component reference.
    
    The query was forwarded to the associate target only for a full reference
    to the associate name.  But a non-full simply-contiguous section reference
    of an associate name associated with a non-contiguous target is not simply
    contiguous.  Remove the condition on the full array reference from the
    check guarding the forwarding.
    
    With the condition on the full array reference removed, a non-contiguous
    array section of an associate name associated with a simply contiguous
    target should continue to return false.  Continue checking the array
    section even if the query forwarded to the associate target returned
    true.
    
            PR fortran/127701
    
    gcc/fortran/ChangeLog:
    
            * expr.cc (gfc_is_simply_contiguous): Only forward to the associate
            target if there is no subreference after the associate name.  Also
            forward to the associate target for a non-full array reference.
            Continue checking the array reference even if the associate target
            is simply contiguous.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/contiguous_18.f90: New test.

Diff:
---
 gcc/fortran/expr.cc                         |  9 +++---
 gcc/testsuite/gfortran.dg/contiguous_18.f90 | 46 +++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc
index bdd7a2008226..68663fe35d19 100644
--- a/gcc/fortran/expr.cc
+++ b/gcc/fortran/expr.cc
@@ -6490,12 +6490,13 @@ gfc_is_simply_contiguous (gfc_expr *expr, bool strict, 
bool permit_element)
     return false;
 
   /* An associate variable may point to a non-contiguous target.  */
-  if (ar && ar->type == AR_FULL
+  if (!part_ref
       && sym->attr.associate_var && !sym->attr.contiguous
       && sym->assoc
-      && sym->assoc->target)
-    return gfc_is_simply_contiguous (sym->assoc->target, strict,
-                                    permit_element);
+      && sym->assoc->target
+      && !gfc_is_simply_contiguous (sym->assoc->target, strict,
+                                   permit_element))
+    return false;
 
   if (!ar || ar->type == AR_FULL)
     return true;
diff --git a/gcc/testsuite/gfortran.dg/contiguous_18.f90 
b/gcc/testsuite/gfortran.dg/contiguous_18.f90
new file mode 100644
index 000000000000..8e35575896ab
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/contiguous_18.f90
@@ -0,0 +1,46 @@
+! { dg-do compile }
+!
+! PR fortran/127701
+! Check that a simply contiguous reference is correctly recognized as such when
+! it is a subreference of an associate name.
+
+program prog
+   implicit none
+   integer, parameter :: l = 7
+   integer, parameter :: m = 5
+   integer, parameter :: s = 2
+   integer, parameter :: n = (m + s - 1) / s
+   type :: t1
+      integer :: c1(l,l)
+   end type
+   type(t1), target :: x(m)
+   integer, target :: y(m,m)
+   integer :: i, j
+   x = (/ (t1(reshape([ (i+j, j=1,l*l) ], [l,l])), i=1,size(x,1)) /)
+   call sub1(x(::s))
+   y = reshape((/ (i*i, i=1,size(y)) /), shape(y))
+   call sub2(y(::s,:))
+   call sub3(y)
+contains
+   subroutine sub1(a)
+      type(t1), target :: a(:)
+      integer, contiguous, pointer :: p(:)
+      associate(b => a)
+         p(1:l*l) => b(1)%c1  ! no error
+      end associate
+   end subroutine
+   subroutine sub2(a)
+      integer, target :: a(:,:)
+      integer, contiguous, pointer :: p(:)
+      associate(b => a)
+         p(1:n*m) => b(:,:)   ! { dg-error "must be rank 1 or simply 
contiguous" }
+      end associate
+   end subroutine
+   subroutine sub3(a)
+      integer, target :: a(m,m)
+      integer, contiguous, pointer :: p(:)
+      associate(b => a)
+         p(1:n*m) => b(::s,:) ! { dg-error "must be rank 1 or simply 
contiguous" }
+      end associate
+   end subroutine
+end program

Reply via email to