aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndre Vehreschild <vehre@gcc.gnu.org>2024-08-23 09:07:09 +0200
committerAndre Vehreschild <vehre@gcc.gnu.org>2024-09-19 09:52:23 +0200
commit361903ad1affd508bafdb9b771d6a6ffc98a2100 (patch)
tree5b6ceb6472bef3fa21623833de5bc1fe67b47e95 /gcc
parent08aba2dd8c9390b6131cca0aac069f97eeddc9d2 (diff)
downloadgcc-361903ad1affd508bafdb9b771d6a6ffc98a2100.zip
gcc-361903ad1affd508bafdb9b771d6a6ffc98a2100.tar.gz
gcc-361903ad1affd508bafdb9b771d6a6ffc98a2100.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/trans-array.cc16
-rw-r--r--gcc/fortran/trans-expr.cc2
-rw-r--r--gcc/testsuite/gfortran.dg/coarray/alloc_comp_9.f9023
3 files changed, 32 insertions, 9 deletions
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 8c35926..838b6d3 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -9417,10 +9417,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;
@@ -9474,7 +9473,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;
@@ -9505,7 +9504,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
@@ -9684,7 +9683,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);
@@ -10414,8 +10413,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 07e28a9..01cf3f0 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -9645,7 +9645,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 0000000..d8e739a
--- /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 <gscfq@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
+