Hi all, attached patch fixes an ICE in gimplify by assuring that the corank of a non-pointer, non-coarray array component in a derived type is zero. Previously (erroneously) the full corank of the type has been used. There is one exception for pointer typed array components in coarray derived types. These can be associated only to coarray array targets (compare F2018 C1024 and C1026). Therefore for those the corank is still propagated.
Regtests ok on x86_64-pc-linux-gnu / Fedora 39. Ok for mainline? Regards, Andre -- Andre Vehreschild * Email: vehre ad gmx dot de
From 0ba7ab80bce08f0b3c6f1f4928f95c87b4bbd39d Mon Sep 17 00:00:00 2001 From: Andre Vehreschild <ve...@gcc.gnu.org> Date: Fri, 16 Aug 2024 15:07:39 +0200 Subject: [PATCH] [Fortran] Fix coarray rank for non-coarrays in derived types. [PR86468] The corank was propagated to array components in derived types. Fix this by setting a zero corank when the array component is not a pointer. For pointer typed array components propagate the corank of the derived type to allow associating the component to a coarray. gcc/fortran/ChangeLog: PR fortran/86468 * trans-intrinsic.cc (conv_intrinsic_move_alloc): Correct comment. * trans-types.cc (gfc_sym_type): Pass coarray rank, not false. (gfc_get_derived_type): Only propagate codimension for coarrays and pointers to array components in derived typed coarrays. gcc/testsuite/ChangeLog: * gfortran.dg/coarray_lib_this_image_2.f90: Fix array rank in tree dump scan. * gfortran.dg/coarray_lib_token_4.f90: Same. * gfortran.dg/coarray/move_alloc_2.f90: New test. --- gcc/fortran/trans-intrinsic.cc | 2 +- gcc/fortran/trans-types.cc | 16 +++--- .../gfortran.dg/coarray/move_alloc_2.f90 | 55 +++++++++++++++++++ .../gfortran.dg/coarray_lib_this_image_2.f90 | 2 +- .../gfortran.dg/coarray_lib_token_4.f90 | 4 +- 5 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/coarray/move_alloc_2.f90 diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc index 586fc65f21d..ceda7843fa9 100644 --- a/gcc/fortran/trans-intrinsic.cc +++ b/gcc/fortran/trans-intrinsic.cc @@ -12906,7 +12906,7 @@ conv_intrinsic_move_alloc (gfc_code *code) gfc_add_expr_to_block (&block, tmp); } - /* Move the pointer and update the array descriptor data. */ + /* Copy the array descriptor data. */ gfc_add_modify_loc (input_location, &block, to_se.expr, from_se.expr); /* Set "from" to NULL. */ diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc index bc582085f57..ba2ffba8ec1 100644 --- a/gcc/fortran/trans-types.cc +++ b/gcc/fortran/trans-types.cc @@ -2386,7 +2386,7 @@ gfc_sym_type (gfc_symbol * sym, bool is_bind_c) else if (sym->attr.allocatable) akind = GFC_ARRAY_ALLOCATABLE; type = gfc_build_array_type (type, sym->as, akind, restricted, - sym->attr.contiguous, false); + sym->attr.contiguous, sym->as->corank); } } else @@ -2909,12 +2909,14 @@ gfc_get_derived_type (gfc_symbol * derived, int codimen) else akind = GFC_ARRAY_ALLOCATABLE; /* Pointers to arrays aren't actually pointer types. The - descriptors are separate, but the data is common. */ - field_type = gfc_build_array_type (field_type, c->as, akind, - !c->attr.target - && !c->attr.pointer, - c->attr.contiguous, - codimen); + descriptors are separate, but the data is common. Every + array pointer in a coarray derived type needs to provide space + for the coarray management, too. Therefore treat coarrays + and pointers to coarrays in derived types the same. */ + field_type = gfc_build_array_type ( + field_type, c->as, akind, !c->attr.target && !c->attr.pointer, + c->attr.contiguous, + c->attr.codimension || c->attr.pointer ? codimen : 0); } else field_type = gfc_get_nodesc_array_type (field_type, c->as, diff --git a/gcc/testsuite/gfortran.dg/coarray/move_alloc_2.f90 b/gcc/testsuite/gfortran.dg/coarray/move_alloc_2.f90 new file mode 100644 index 00000000000..4a8e54ced6b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/coarray/move_alloc_2.f90 @@ -0,0 +1,55 @@ +!{ dg-do run } + +! Check gimplify with checking works. [PR86468] +! This rather complicated code is needed to produce two "different" +! types in the move_alloc. + +! Contributed by Juergen Reuter <juergen.reu...@desy.de> + +module classes + implicit none + private + public :: wrapped_coarray + + type :: wrapped_point + integer, allocatable :: point(:) + contains + procedure :: add => wrapped_point_add + end type wrapped_point + + type :: wrapped_coarray + type(wrapped_point), allocatable :: caf(:)[:] + end type wrapped_coarray + +contains + + subroutine wrapped_point_add(self, to_add) + class(wrapped_point), intent(inout) :: self + integer, intent(in) :: to_add + integer, allocatable :: point(:) + integer :: points_number + + if (allocated(self%point)) then + points_number = size(self%point, dim=1) + allocate(point(1:points_number+1)) + point(1:points_number) = self%point + point(points_number+1) = to_add + call move_alloc(from=point, to=self%point) + else + allocate(self%point(1)) + self%point(1) = to_add + end if + end subroutine wrapped_point_add +end module classes + +program test + use classes + implicit none + + type(wrapped_coarray) :: foo + allocate(foo%caf(99)[*]) + call foo%caf(32)%add(this_image()) + call foo%caf(32)%add(this_image()) + if (any (foo%caf(32)%point /= [this_image(), this_image()])) stop 1 +end program test + diff --git a/gcc/testsuite/gfortran.dg/coarray_lib_this_image_2.f90 b/gcc/testsuite/gfortran.dg/coarray_lib_this_image_2.f90 index 7b44c73211b..a27d7407833 100644 --- a/gcc/testsuite/gfortran.dg/coarray_lib_this_image_2.f90 +++ b/gcc/testsuite/gfortran.dg/coarray_lib_this_image_2.f90 @@ -16,7 +16,7 @@ contains end subroutine bar end -! { dg-final { scan-tree-dump-times "bar \\(struct array01_real\\(kind=4\\) & restrict x, void \\* restrict caf_token.., integer\\(kind=\[48\]\\) caf_offset..\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "bar \\(struct array02_real\\(kind=4\\) & restrict x, void \\* restrict caf_token.., integer\\(kind=\[48\]\\) caf_offset..\\)" 1 "original" } } ! { dg-final { scan-tree-dump-times "mylcobound = 5;" 1 "original" } } ! { dg-final { scan-tree-dump-times "parm...dim\\\[1\\\].lbound = 5;" 1 "original" } } ! { dg-final { scan-tree-dump-times "myucobound =\[^\n\r\]* parm...dim\\\[1\\\].lbound \\+ \[^\n\r\]*_gfortran_caf_num_images \\(0, -1\\).? \\+ -?\[0-9\]+\\);" 1 "original" } } diff --git a/gcc/testsuite/gfortran.dg/coarray_lib_token_4.f90 b/gcc/testsuite/gfortran.dg/coarray_lib_token_4.f90 index b09552a7f03..b69aa5fce89 100644 --- a/gcc/testsuite/gfortran.dg/coarray_lib_token_4.f90 +++ b/gcc/testsuite/gfortran.dg/coarray_lib_token_4.f90 @@ -35,9 +35,9 @@ end program test_caf ! { dg-final { scan-tree-dump-times "expl \\(integer\\(kind=4\\).0:. . restrict z, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+\\)" 1 "original" } } ! -! { dg-final { scan-tree-dump-times "bar \\(struct array01_integer\\(kind=4\\) & restrict y, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "bar \\(struct array02_integer\\(kind=4\\) & restrict y, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+\\)" 1 "original" } } ! -! { dg-final { scan-tree-dump-times "foo \\(struct array01_integer\\(kind=4\\) & restrict x, struct array01_integer\\(kind=4\\) & restrict y, integer\\(kind=4\\) & restrict test, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "foo \\(struct array02_integer\\(kind=4\\) & restrict x, struct array02_integer\\(kind=4\\) & restrict y, integer\\(kind=4\\) & restrict test, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+\\)" 1 "original" } } ! ! { dg-final { scan-tree-dump-times "bar \\(&parm.\[0-9\]+, caf_token.\[0-9\]+, \\(\\(integer\\(kind=.\\)\\) parm.\[0-9\]+.data - \\(integer\\(kind=.\\)\\) x.\[0-9\]+\\) \\+ caf_offset.\[0-9\]+\\);" 1 "original" } } ! -- 2.46.0