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