Hi all,

attached patch fixes a gimplification error when a pointer remapping on derived
type's components with deferred arrays is made. The issue boiled down to the
dependency analysis being to loose. It saw a dependency as soon as both sides
of the => had a derived type, independent of the actual derived types used. The
patch therefore extends the dependency analysis to compare also the derived
types (symbols).

This fixes the PR, but not really the problem, because when say a
obj(i)%arr(2:5) => obj(i)%arr(1:4) is done we run into the same issue. I don't
have a solution for that error. It might  be needed to prevent generating the
parm.NN variable for the lhs, because that is mostly useless there. (Or I don't
understand (yet) how to use it).

Regstests ok on x86_64-pc-linux-gnu / F41. Ok for mainline or other suggestions?

Regards,
        Andre
--
Andre Vehreschild * Email: vehre ad gmx dot de
From ab201d8001cd14bb1c3cf7cd99a34b927af1f32e Mon Sep 17 00:00:00 2001
From: Andre Vehreschild <ve...@gcc.gnu.org>
Date: Wed, 5 Mar 2025 15:18:48 +0100
Subject: [PATCH] Fortran: Fix gimplification error for pointer remapping in
 forall [PR107143]

Enhance dependency checking for data pointers to check for same derived
type and not only for a type being a derived type.  This prevent
generation of a descriptor for a function call, that is unsuitable in
forall's pointer assignment.

	PR fortran/107143

gcc/fortran/ChangeLog:

	* dependency.cc (check_data_pointer_types): Do not just compare
	for derived type, but for same derived type.

gcc/testsuite/ChangeLog:

	* gfortran.dg/forall_20.f90: New test.
---
 gcc/fortran/dependency.cc               |  3 +-
 gcc/testsuite/gfortran.dg/forall_20.f90 | 40 +++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gfortran.dg/forall_20.f90

diff --git a/gcc/fortran/dependency.cc b/gcc/fortran/dependency.cc
index 6b3affa6057..38eb114711b 100644
--- a/gcc/fortran/dependency.cc
+++ b/gcc/fortran/dependency.cc
@@ -1250,7 +1250,8 @@ check_data_pointer_types (gfc_expr *expr1, gfc_expr *expr2)
   sym2 = expr2->symtree->n.sym;

   /* Keep it simple for now.  */
-  if (sym1->ts.type == BT_DERIVED && sym2->ts.type == BT_DERIVED)
+  if (sym1->ts.type == BT_DERIVED && sym2->ts.type == BT_DERIVED
+      && sym1->ts.u.derived == sym2->ts.u.derived)
     return false;

   if (sym1->attr.pointer)
diff --git a/gcc/testsuite/gfortran.dg/forall_20.f90 b/gcc/testsuite/gfortran.dg/forall_20.f90
new file mode 100644
index 00000000000..63392bd6aad
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/forall_20.f90
@@ -0,0 +1,40 @@
+!{ dg-do run }
+!
+! Check pointer aliasing is done w/o temp.
+! Contributed by Arseny Solokha  <asolo...@gmx.com>
+
+program pr107143
+  type ta
+     integer, POINTER :: ip(:)
+  end type ta
+
+  type tb
+     integer, POINTER :: ip(:,:)
+  end type tb
+
+  integer, parameter :: cnt = 3
+  type(ta) :: a(cnt)
+  type(tb) :: b(cnt)
+  integer, target :: arr(8) = [1,2,3,4,5,6,7,8]
+
+  do i = 1, cnt
+    allocate(a(i)%ip(8), SOURCE=arr * i)
+  end do
+  call s5(b, a, 2, 4)
+
+  do i = 1, cnt
+    if (any(a(i)%ip /= arr * i)) stop i
+  end do
+
+contains
+
+subroutine s5(y,z,n1,n2)
+
+  type(tb) :: y(:)
+  type(ta), TARGET :: z(:)
+
+  forall (i=1:cnt)
+    y(i)%ip(1:n1,1:n2) => z(i)%ip
+  end forall
+end subroutine s5
+end program
--
2.48.1

Reply via email to