https://gcc.gnu.org/g:361903ad1affd508bafdb9b771d6a6ffc98a2100
commit r15-3707-g361903ad1affd508bafdb9b771d6a6ffc98a2100 Author: Andre Vehreschild <ve...@gcc.gnu.org> Date: Fri Aug 23 09:07:09 2024 +0200 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. Diff: --- gcc/fortran/trans-array.cc | 16 +++++++-------- gcc/fortran/trans-expr.cc | 2 +- gcc/testsuite/gfortran.dg/coarray/alloc_comp_9.f90 | 23 ++++++++++++++++++++++ 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 8c35926436d7..838b6d3da800 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 07e28a9f7a8d..01cf3f0ff148 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 000000000000..d8e739a07d87 --- /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 +