https://gcc.gnu.org/g:bb2324769c5a03e275de00416659e624c97f1442
commit r15-2910-gbb2324769c5a03e275de00416659e624c97f1442 Author: Andre Vehreschild <ve...@gcc.gnu.org> Date: Fri Aug 9 16:19:23 2024 +0200 Fix ICE in build_function_decl [PR116292] Fix ICE by getting the vtype only when a derived or class type is prevent. Also take care about the _len component for unlimited polymorphics. gcc/fortran/ChangeLog: PR fortran/116292 * trans-intrinsic.cc (conv_intrinsic_move_alloc): Get the vtab only for derived types and classes and adjust _len for class types. gcc/testsuite/ChangeLog: * gfortran.dg/move_alloc_19.f90: New test. Diff: --- gcc/fortran/trans-intrinsic.cc | 20 ++++++++++++++--- gcc/testsuite/gfortran.dg/move_alloc_19.f90 | 34 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc index 150cb9ff963b..84a378ef310c 100644 --- a/gcc/fortran/trans-intrinsic.cc +++ b/gcc/fortran/trans-intrinsic.cc @@ -12764,9 +12764,12 @@ conv_intrinsic_move_alloc (gfc_code *code) gfc_symbol *vtab; from_tree = from_se.expr; - vtab = gfc_find_vtab (&from_expr->ts); - gcc_assert (vtab); - from_se.expr = gfc_get_symbol_decl (vtab); + if (to_expr->ts.type == BT_CLASS) + { + vtab = gfc_find_vtab (&from_expr->ts); + gcc_assert (vtab); + from_se.expr = gfc_get_symbol_decl (vtab); + } } gfc_add_block_to_block (&block, &from_se.pre); @@ -12811,6 +12814,15 @@ conv_intrinsic_move_alloc (gfc_code *code) gfc_class_set_vptr (&block, to_se.expr, from_se.expr); if (from_is_class) gfc_reset_vptr (&block, from_expr); + if (UNLIMITED_POLY (to_expr)) + { + tree to_len = gfc_class_len_get (to_se.class_container); + tmp = from_expr->ts.type == BT_CHARACTER && from_se.string_length + ? from_se.string_length + : size_zero_node; + gfc_add_modify_loc (input_location, &block, to_len, + fold_convert (TREE_TYPE (to_len), tmp)); + } } if (from_is_scalar) @@ -12825,6 +12837,8 @@ conv_intrinsic_move_alloc (gfc_code *code) input_location, &block, from_se.string_length, build_int_cst (TREE_TYPE (from_se.string_length), 0)); } + if (UNLIMITED_POLY (from_expr)) + gfc_reset_len (&block, from_expr); return gfc_finish_block (&block); } diff --git a/gcc/testsuite/gfortran.dg/move_alloc_19.f90 b/gcc/testsuite/gfortran.dg/move_alloc_19.f90 new file mode 100644 index 000000000000..d23d9809ba11 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/move_alloc_19.f90 @@ -0,0 +1,34 @@ +!{ dg-do run } + +! Check PR 116292 is fixed. + +! Contributed by Harald Anlauf <anl...@gcc.gnu.org> +! Sam James <sja...@gcc.gnu.org> + +program move_alloc_19 + character, allocatable :: buffer, dummy, dummy2 + class(*), allocatable :: poly + + dummy = 'C' + dummy2 = 'A' + call s() + if (allocated (dummy)) stop 1 + if (allocated (dummy2)) stop 2 + if (.not. allocated (buffer)) stop 3 + if (.not. allocated (poly)) stop 4 + if (buffer /= 'C') stop 5 + select type (poly) + type is (character(*)) + if (poly /= 'A') stop 6 + if (len (poly) /= 1) stop 7 + class default + stop 8 + end select + deallocate (poly, buffer) +contains + subroutine s + call move_alloc (dummy, buffer) + call move_alloc (dummy2, poly) + end +end +