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

Reply via email to