Dear All, This patch allows the assignment of class array constructors to derived type arrays. It is straightforward enough that the ChangeLogs and the comment are sufficient explanation.
Bootstraps and regtests on FC23/x86_64 - OK for all three branches? Paul 2017-11-04 Paul Thomas <pa...@gcc.gnu.org> PR fortran/78641 * resolve.c (resolve_ordinary_assign): Do not add the _data component for class valued array constructors being assigned to derived type arrays. * trans-array.c (gfc_trans_array_ctor_element): Take the _data of class valued elements for assignment to derived type arrays. 2017-11-04 Paul Thomas <pa...@gcc.gnu.org> PR fortran/78641 * gfortran.dg/class_66.f90: New test.
Index: gcc/fortran/resolve.c =================================================================== *** gcc/fortran/resolve.c (revision 254403) --- gcc/fortran/resolve.c (working copy) *************** resolve_ordinary_assign (gfc_code *code, *** 10324,10330 **** /* Assign the 'data' of a class object to a derived type. */ if (lhs->ts.type == BT_DERIVED ! && rhs->ts.type == BT_CLASS) gfc_add_data_component (rhs); bool caf_convert_to_send = flag_coarray == GFC_FCOARRAY_LIB --- 10324,10331 ---- /* Assign the 'data' of a class object to a derived type. */ if (lhs->ts.type == BT_DERIVED ! && rhs->ts.type == BT_CLASS ! && rhs->expr_type != EXPR_ARRAY) gfc_add_data_component (rhs); bool caf_convert_to_send = flag_coarray == GFC_FCOARRAY_LIB Index: gcc/fortran/trans-array.c =================================================================== *** gcc/fortran/trans-array.c (revision 254403) --- gcc/fortran/trans-array.c (working copy) *************** gfc_trans_array_ctor_element (stmtblock_ *** 1580,1585 **** --- 1580,1596 ---- } } } + else if (GFC_CLASS_TYPE_P (TREE_TYPE (se->expr)) + && !GFC_CLASS_TYPE_P (gfc_get_element_type (TREE_TYPE (desc)))) + { + /* Assignment of a CLASS array constructor to a derived type array. */ + if (expr->expr_type == EXPR_FUNCTION) + se->expr = gfc_evaluate_now (se->expr, pblock); + se->expr = gfc_class_data_get (se->expr); + se->expr = build_fold_indirect_ref_loc (input_location, se->expr); + se->expr = fold_convert (TREE_TYPE (tmp), se->expr); + gfc_add_modify (&se->pre, tmp, se->expr); + } else { /* TODO: Should the frontend already have done this conversion? */ Index: gcc/testsuite/gfortran.dg/class_66.f90 =================================================================== *** gcc/testsuite/gfortran.dg/class_66.f90 (nonexistent) --- gcc/testsuite/gfortran.dg/class_66.f90 (working copy) *************** *** 0 **** --- 1,28 ---- + ! { dg- do run } + ! + ! Test the fix for PR78641 in which an ICE occured on assignment + ! of a class array constructor to a derived type array. + ! + ! Contributed by Damian Rouson <dam...@sourceryinstitute.org> + ! + implicit none + type foo + integer :: i = 99 + end type + type(foo) :: bar(4) + class(foo), allocatable :: barfoo + + allocate(barfoo,source = f(11)) + bar = [f(33), [f(22), barfoo], f(1)] + if (any (bar%i .ne. [33, 22, 11, 1])) call abort + deallocate (barfoo) + + contains + + function f(arg) result(foobar) + class(foo), allocatable :: foobar + integer :: arg + allocate(foobar,source = foo(arg)) + end function + + end program