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

Reply via email to