diff mbox series

Update: [patch, libfortran] Fix EOF handling in array I/O

Message ID 63511ede-0d43-ac37-8cc3-dd1885b63535@netcologne.de
State New
Headers show
Series Update: [patch, libfortran] Fix EOF handling in array I/O | expand

Commit Message

Thomas Koenig Nov. 24, 2019, 10:25 a.m. UTC
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.
diff mbox series

Patch

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];
+		}
 	    }
 	}
     }