Dear All, When I first posted it in Bugzilla, I thought that this patch is too kludgey by far. However, it has grown on me and I now think that it is the right thing to do. The patch is self-explanatory.
Bootstrapped and regtested on FC17/x86_64 - OK for trunk and 4.7/4.8 with an appropriate delay? Cheers Paul 2013-11-04 Paul Thomas <pa...@gcc.gnu.org> PR fortran/58771 * trans-io.c (transfer_expr): If the backend_decl for a derived type is missing, build it with gfc_typenode_for_spec. 2013-11-04 Paul Thomas <pa...@gcc.gnu.org> PR fortran/58771 * gfortran.dg/derived_external_function_1.f90 : New test
Index: gcc/fortran/trans-io.c =================================================================== *** gcc/fortran/trans-io.c (revision 204285) --- gcc/fortran/trans-io.c (working copy) *************** transfer_expr (gfc_se * se, gfc_typespec *** 2146,2151 **** --- 2146,2157 ---- expr = build_fold_indirect_ref_loc (input_location, expr); + /* Make sure that the derived type has been built. An external + function, if only referenced in an io statement requires this + check (see PR58771). */ + if (ts->u.derived->backend_decl == NULL_TREE) + tmp = gfc_typenode_for_spec (ts); + for (c = ts->u.derived->components; c; c = c->next) { field = c->backend_decl; Index: gcc/testsuite/gfortran.dg/derived_external_function_1.f90 =================================================================== *** gcc/testsuite/gfortran.dg/derived_external_function_1.f90 (revision 0) --- gcc/testsuite/gfortran.dg/derived_external_function_1.f90 (working copy) *************** *** 0 **** --- 1,27 ---- + ! { dg-do run } + ! + ! PR fortran/58771 + ! + ! Contributed by Vittorio Secca <zec...@gmail.com> + ! + ! ICEd on the write statement with f() because the derived type backend + ! declaration not built. + ! + module m + type t + integer(4) g + end type + end + + type(t) function f() result(ff) + use m + ff%g = 42 + end + + use m + character (20) :: line1, line2 + type(t) f + write (line1, *), f() + write (line2, *), 42_4 + if (line1 .ne. line2) call abort + end