This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Update: [patch, libfortran] Fix EOF handling in array I/O
Here's an update to the previous patch.
Upon reflection, I think it is better for performance to have two
versions of the loop so the test is only performed when it is
needed.
So, OK for trunk?
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.
Index: io/transfer.c
===================================================================
--- io/transfer.c (Revision 278025)
+++ io/transfer.c (Arbeitskopie)
@@ -2542,26 +2542,62 @@ transfer_array_inner (st_parameter_dt *dtp, gfc_ar
data = GFC_DESCRIPTOR_DATA (desc);
- while (data)
+ /* When reading, we need to check endfile conditions so we do not miss
+ an END=label. Make this separate so we do not have an extra test
+ in a tight loop when it is not needed. */
+
+ if (dtp->u.p.current_unit && dtp->u.p.mode == READING)
{
- dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
- data += stride0 * tsize;
- count[0] += tsize;
- n = 0;
- while (count[n] == extent[n])
+ while (data)
{
- count[n] = 0;
- data -= stride[n] * extent[n];
- n++;
- if (n == rank)
+ if (unlikely (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;
+ n = 0;
+ while (count[n] == extent[n])
{
- data = NULL;
- break;
+ count[n] = 0;
+ data -= stride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ data = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ data += stride[n];
+ }
}
- else
+ }
+ }
+ else
+ {
+ while (data)
+ {
+ dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
+ data += stride0 * tsize;
+ count[0] += tsize;
+ n = 0;
+ while (count[n] == extent[n])
{
- count[n]++;
- data += stride[n];
+ count[n] = 0;
+ data -= stride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ data = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ data += stride[n];
+ }
}
}
}
! { dg-do run }
! { dg-options "-ffrontend-optimize" }
! PR 92569 - the EOF condition was not recognized with
! -ffrontend-optimize. Originjal test case by Bill Lipa.
program main
implicit none
real(kind=8) :: tdat(1000,10)
real(kind=8) :: res (10, 3)
integer :: i, j, k, np
open (unit=20, status="scratch")
res = reshape([(real(i),i=1,30)], shape(res))
write (20,'(10G12.5)') res
rewind 20
do j = 1,1000
read (20,*,end=1)(tdat(j,k),k=1,10)
end do
1 continue
np = j-1
if (np /= 3) stop 1
if (any(transpose(res) /= tdat(1:np,:))) stop 2
end program main