[Patch, fortran] PR24862 IO for arrays of derived type.

Janne Blomqvist jblomqvi@cc.hut.fi
Thu Nov 17 09:44:00 GMT 2005


Hello,

my transfer_array patch that was committed about two months ago didn't
handle IO for arrays of derived type correctly. This patch fixes it.

The control flow in the new version is a bit convoluted, so I'd be
happy to recieve suggestions on how to improve it.

-- 
Janne Blomqvist
-------------- next part --------------
fortran ChangeLog:
	
2005-11-17  Janne Blomqvist  <jb@gcc.gnu.org>

	PR fortran/24862
	* trans-io.c (gfc_trans_transfer): Handle arrays of derived type.

testsuite ChangeLog:

2005-11-17  Janne Blomqvist  <jb@gcc.gnu.org>

	PR fortran/24862
	* gfortran.dg/arrayio_derived_1.f90: New test.
-------------- next part --------------
Index: trans-io.c
===================================================================
--- trans-io.c	(revision 107115)
+++ trans-io.c	(working copy)
@@ -1640,11 +1640,41 @@ gfc_trans_transfer (gfc_code * code)
 
   if (ss == gfc_ss_terminator)
     {
+      /* Transfer a scalar value.  */
       gfc_conv_expr_reference (&se, expr);
       transfer_expr (&se, &expr->ts, se.expr);
     }
-  else if (expr->ts.type == BT_DERIVED)
+  else
     {
+      /* Transfer an array. There are 3 options:
+      1) An array of an intrinsic type. This is handled by transfering
+	 the descriptor to the library.
+      2) A derived type containing an array. Scalarized by the frontend.
+      3) An array of derived type. Scalarized by the frontend.
+      */
+      if (expr->ts.type != BT_DERIVED)
+	{
+	  /* Get the descriptor.  */
+	  gfc_conv_expr_descriptor (&se, expr, ss);
+	  /* If it's not an array of derived type, transfer the array
+	     descriptor to the library.  */
+	  tmp = gfc_get_dtype (TREE_TYPE (se.expr));
+	  if (((TREE_INT_CST_LOW (tmp) & GFC_DTYPE_TYPE_MASK) 
+	       >> GFC_DTYPE_TYPE_SHIFT) != GFC_DTYPE_DERIVED)
+	    {
+	      tmp = gfc_build_addr_expr (NULL, se.expr);
+	      transfer_array_desc (&se, &expr->ts, tmp);
+	      goto finish_block_label;
+	    }
+	  else
+	    {
+	      /* Cleanup the mess getting the descriptor caused.  */
+	      expr = code->expr;
+	      ss = gfc_walk_expr (expr);
+	      gfc_init_se (&se, NULL);
+	    }
+	}
+      
       /* Initialize the scalarizer.  */
       gfc_init_loopinfo (&loop);
       gfc_add_ss_to_loop (&loop, ss);
@@ -1663,13 +1693,8 @@ gfc_trans_transfer (gfc_code * code)
       gfc_conv_expr_reference (&se, expr);
       transfer_expr (&se, &expr->ts, se.expr);
     }
-  else
-    {
-      /* Pass the array descriptor to the library.  */
-      gfc_conv_expr_descriptor (&se, expr, ss);
-      tmp = gfc_build_addr_expr (NULL, se.expr);
-      transfer_array_desc (&se, &expr->ts, tmp);
-    }
+
+ finish_block_label:
 
   gfc_add_block_to_block (&body, &se.pre);
   gfc_add_block_to_block (&body, &se.post);
-------------- next part --------------
! { dg-do run }
! PR 24862: IO for arrays of derived type handled incorrectly.
module gfortran3

    type tp
        integer :: i
    end type
contains
    subroutine inittp(X)
        type(tp), intent(inout) :: X(:)
        X%i = 256
    end subroutine inittp

    subroutine test(x)
        type(tp), intent(in) :: x(:)

        write(*,*) x%i
        write(*,*) x
    end subroutine test
end module

program arrayio_derived_1
    use gfortran3
    implicit none
    type(tp) :: Y(5)

    call inittp(Y)
    write(*,*) Y%i
    call test(Y)
end program arrayio_derived_1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 185 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20051117/30dcdc14/attachment.sig>


More information about the Gcc-patches mailing list