Hi all,

attached patch fixes an ICE during trans-phase when allocatable components in
derived typed coarrays were nested. I am nearly convinced, that the ICE is
mostly fixed by pr86468, because I get a slightly different ICE. Nevertheless
was the executable crashing with -fcoarray=lib because the deep copy was not
inserted in the coarray case, which is fixed by this patch now. Furthermore did
I correct a comment, that was describing the inverse of the code following.

Regtests ok on x86_64-pc-linux-gnu / Fedora 39. Ok for mainline?

Regards,
        Andre
--
Andre Vehreschild * Email: vehre ad gmx dot de
From db6ca3808956b6e7c6950cbf572f2bba0995e03e Mon Sep 17 00:00:00 2001
From: Andre Vehreschild <ve...@gcc.gnu.org>
Date: Fri, 23 Aug 2024 09:07:09 +0200
Subject: [PATCH] [Fortran] Fix deep copy allocatable components in coarrays.
 [PR85002]

Fix code for deep copy of allocatable components in derived type nested
structures generated, but not inserted when the copy had to be done in
a coarray.  Additionally fix a comment.

gcc/fortran/ChangeLog:

	PR fortran/85002
	* trans-array.cc (duplicate_allocatable_coarray): Allow adding
	of deep copy code in the when-allocated case.  Add bounds
	computation before condition, because coarrays need the bounds
	also when not allocated.
	(structure_alloc_comps): Duplication in the coarray case is done
	already, omit it.  Add the deep-code when duplication a coarray.
	* trans-expr.cc (gfc_trans_structure_assign): Fix comment.

gcc/testsuite/ChangeLog:

	* gfortran.dg/coarray/alloc_comp_9.f90: New test.
---
 gcc/fortran/trans-array.cc                    | 16 ++++++-------
 gcc/fortran/trans-expr.cc                     |  2 +-
 .../gfortran.dg/coarray/alloc_comp_9.f90      | 23 +++++++++++++++++++
 3 files changed, 32 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/coarray/alloc_comp_9.f90

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index ea5fff2e0c2..3472fc5b636 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -9505,10 +9505,9 @@ gfc_duplicate_allocatable_nocopy (tree dest, tree src, tree type, int rank)
 				NULL_TREE, NULL_TREE);
 }

-
 static tree
-duplicate_allocatable_coarray (tree dest, tree dest_tok, tree src,
-			       tree type, int rank)
+duplicate_allocatable_coarray (tree dest, tree dest_tok, tree src, tree type,
+			       int rank, tree add_when_allocated)
 {
   tree tmp;
   tree size;
@@ -9562,7 +9561,7 @@ duplicate_allocatable_coarray (tree dest, tree dest_tok, tree src,
       gfc_add_modify (&globalblock, tmp, build_int_cst (TREE_TYPE (tmp), rank));

       if (rank)
-	nelems = gfc_full_array_size (&block, src, rank);
+	nelems = gfc_full_array_size (&globalblock, src, rank);
       else
 	nelems = integer_one_node;

@@ -9593,7 +9592,7 @@ duplicate_allocatable_coarray (tree dest, tree dest_tok, tree src,
 				 fold_convert (size_type_node, size));
       gfc_add_expr_to_block (&block, tmp);
     }
-
+  gfc_add_expr_to_block (&block, add_when_allocated);
   tmp = gfc_finish_block (&block);

   /* Null the destination if the source is null; otherwise do
@@ -9772,7 +9771,7 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, tree dest,
 	 gfc_duplicate_allocatable (), where the deep copy code is just added
 	 into the if's body, by adding tmp (the deep copy code) as last
 	 argument to gfc_duplicate_allocatable ().  */
-      if (purpose == COPY_ALLOC_COMP
+      if (purpose == COPY_ALLOC_COMP && caf_mode == 0
 	  && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (dest)))
 	tmp = gfc_duplicate_allocatable (dest, decl, decl_type, rank,
 					 tmp);
@@ -10502,8 +10501,9 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, tree dest,
 						 c->caf_token,
 						 NULL_TREE);
 		    }
-		  tmp = duplicate_allocatable_coarray (dcmp, dst_tok, comp,
-						       ctype, rank);
+		  tmp
+		    = duplicate_allocatable_coarray (dcmp, dst_tok, comp, ctype,
+						     rank, add_when_allocated);
 		}
 	      else
 		tmp = gfc_duplicate_allocatable (dcmp, comp, ctype, rank,
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 4681a131139..4489490bb7d 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -9692,7 +9692,7 @@ gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init, bool coarray)

       /* Register the component with the caf-lib before it is initialized.
 	 Register only allocatable components, that are not coarray'ed
-	 components (%comp[*]).  Only register when the constructor is not the
+	 components (%comp[*]).  Only register when the constructor is the
 	 null-expression.  */
       if (coarray && !cm->attr.codimension
 	  && (cm->attr.allocatable || cm->attr.pointer)
diff --git a/gcc/testsuite/gfortran.dg/coarray/alloc_comp_9.f90 b/gcc/testsuite/gfortran.dg/coarray/alloc_comp_9.f90
new file mode 100644
index 00000000000..d8e739a07d8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray/alloc_comp_9.f90
@@ -0,0 +1,23 @@
+!{ dg-do run }
+
+! Check PR85002 is fixed.
+! Contributed by G. Steinmetz  <gs...@t-online.de>
+
+program pr85002
+   type t
+      integer, allocatable :: a(:)
+   end type
+   type t2
+      type(t), allocatable :: b(:)
+   end type
+   type(t) :: x
+   type(t2) :: y(2)[*]
+
+   allocate (x%a(2))
+   x%a = 123
+   y = t2([x])
+
+   if (.not. all((/(allocated(y(i)%b), i=1, 2)/))) stop 1
+   if (any ((/(y(i)%b(1)%a /= 123, i=1,2)/))) stop 2
+end
+
--
2.46.0

Reply via email to