diff mbox series

[libfortran] Fix EOF handling in array I/O

Message ID bce3d29f-e35f-2a65-adac-16333c092a51@netcologne.de
State New
Headers show
Series [libfortran] Fix EOF handling in array I/O | expand

Commit Message

Thomas Koenig Nov. 23, 2019, 1:15 p.m. UTC
Hello world,

the attached patch fixes a case where transforming

   do  j = 1,1000
      read (20,*,end=1)(tdat(j,k),k=1,10)
   end do
1 continue

which on straight transformation yields

   DO main:j=1 1000 1
     READ UNIT=20 FMT=-1
     DO main:k=1 10 1
       TRANSFER main:tdat(main:j , main:k)
     END DO
     DT_END END=1
   END DO
1     CONTINUE

into

  DO main:j=1 1000 1
     READ UNIT=20 FMT=-1
     TRANSFER main:tdat(main:j , 1:10:1)
     DT_END END=1
   END DO
1     CONTINUE

with front-end optimization led to a case where the END statement was
not interpreted correctly.

The solution, to jump out of transfer_array_inner when the file
was at its end, was found by Harald; I just added a NULL pointer
check to make some regressions go away.

Regression-tested. OK for all affected branches (trunk, gcc 9 and
gcc 8)?

Regards

	Thomas

Fix EOF handling for arrays.

2019-11-23  Thomas Koenig  <tkoenig@gcc.gnu.org>
         Harald Anlauf <anlauf@gmx.de>

         PR fortran/92569
         * io/transfer.c (transfer_array_inner):  If position is
         at AFTER_ENDFILE in current unit, return from data loop.

2019-11-23  Thomas Koenig  <tkoenig@gcc.gnu.org>
         Harald Anlauf <anlauf@gmx.de>

         PR fortran/92569
         * gfortran.dg/eof_4.f90: New test.

Comments

Thomas Koenig Nov. 23, 2019, 3:24 p.m. UTC | #1
Am 23.11.19 um 14:15 schrieb Thomas Koenig:
>          * gfortran.dg/eof_4.f90: New test.

This should be eof_6.f90 (and will be on commit).

Regards

	Thomas
diff mbox series

Patch

Index: io/transfer.c
===================================================================
--- io/transfer.c	(Revision 278025)
+++ io/transfer.c	(Arbeitskopie)
@@ -2544,6 +2544,10 @@  transfer_array_inner (st_parameter_dt *dtp, gfc_ar
 
   while (data)
     {
+      if (unlikely (dtp->u.p.current_unit
+		    && dtp->u.p.current_unit->endfile == AFTER_ENDFILE))
+	  return;
+
       dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
       data += stride0 * tsize;
       count[0] += tsize;