+2017-10-30 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/80850
+ * trans_expr.c (gfc_conv_procedure_call): When passing a class
+ argument to an unlimited polymorphic dummy, it is wrong to cast
+ the passed expression as unlimited, unless it is unlimited. The
+ correct way is to assign to each of the fields and set the _len
+ field to zero.
+
2017-10-30 Steven G. Kargl <kargl@gcc.gnu.org>
- * resolve.c (resolve_transfer): Set derived to correct symbol for
+ * resolve.c (resolve_transfer): Set derived to correct symbol for
BT_CLASS.
2017-10-29 Jim Wilson <wilson@tuliptree.org>
}
else
{
- gfc_add_modify (&parmse.pre, var,
- fold_build1_loc (input_location,
- VIEW_CONVERT_EXPR,
- type, parmse.expr));
+ /* Since the internal representation of unlimited
+ polymorphic expressions includes an extra field
+ that other class objects do not, a cast to the
+ formal type does not work. */
+ if (!UNLIMITED_POLY (e) && UNLIMITED_POLY (fsym))
+ {
+ tree efield;
+
+ /* Set the _data field. */
+ tmp = gfc_class_data_get (var);
+ efield = fold_convert (TREE_TYPE (tmp),
+ gfc_class_data_get (parmse.expr));
+ gfc_add_modify (&parmse.pre, tmp, efield);
+
+ /* Set the _vptr field. */
+ tmp = gfc_class_vptr_get (var);
+ efield = fold_convert (TREE_TYPE (tmp),
+ gfc_class_vptr_get (parmse.expr));
+ gfc_add_modify (&parmse.pre, tmp, efield);
+
+ /* Set the _len field. */
+ tmp = gfc_class_len_get (var);
+ gfc_add_modify (&parmse.pre, tmp,
+ build_int_cst (TREE_TYPE (tmp), 0));
+ }
+ else
+ {
+ tmp = fold_build1_loc (input_location,
+ VIEW_CONVERT_EXPR,
+ type, parmse.expr);
+ gfc_add_modify (&parmse.pre, var, tmp);
+ ;
+ }
parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
}
}
--- /dev/null
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+!
+! Test the fix for PR80850 in which the _len field was not being
+! set for 'arg' in the call to 'foo'.
+!
+ type :: mytype
+ integer :: i
+ end type
+ class (mytype), pointer :: c
+
+ allocate (c, source = mytype (99_8))
+
+ call foo(c)
+ call bar(c)
+
+ deallocate (c)
+
+contains
+
+ subroutine foo (arg)
+ class(*) :: arg
+ select type (arg)
+ type is (mytype)
+ if (arg%i .ne. 99_8) call abort
+ end select
+ end subroutine
+
+ subroutine bar (arg)
+ class(mytype) :: arg
+ select type (arg)
+ type is (mytype)
+ if (arg%i .ne. 99_8) call abort
+ end select
+ end subroutine
+
+end
+! { dg-final { scan-tree-dump-times "arg.*._len" 1 "original" } }