diff mbox series

PR 44292 Handle large record lengths

Message ID 1511034941-15326-1-git-send-email-blomqvist.janne@gmail.com
State New
Headers show
Series PR 44292 Handle large record lengths | expand

Commit Message

Janne Blomqvist Nov. 18, 2017, 7:55 p.m. UTC
Now that the ABI supports large record lengths, there's a few places
in libgfortran where we need to use larger types. For internal units
which by definition are in-memory, it's enought to use ptrdiff_t, for
external units gfc_offset.

Regtested on x86_64-pc-linux-gnu, Ok for trunk?

libgfortran/ChangeLog:

2017-11-18  Janne Blomqvist  <blomqvist.janne@gmail.com>

	* io/transfer.c (skip_record): Use gfc_offset to handle large
	records.
	(next_record_r): Likewise.
	(sset): Likewise.
	(next_record_w): Use gfc_offset/ptrdiff_t appropriately.
---
 libgfortran/io/transfer.c | 37 ++++++++++++++++++++-----------------
 1 file changed, 20 insertions(+), 17 deletions(-)

Comments

Jerry DeLisle Nov. 18, 2017, 9:39 p.m. UTC | #1
On 11/18/2017 11:55 AM, Janne Blomqvist wrote:
> Now that the ABI supports large record lengths, there's a few places
> in libgfortran where we need to use larger types. For internal units
> which by definition are in-memory, it's enought to use ptrdiff_t, for
> external units gfc_offset.
> 
> Regtested on x86_64-pc-linux-gnu, Ok for trunk?
> 

Looks OK, thanks,

Jerry
diff mbox series

Patch

diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index 5296370..c173447 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -3290,7 +3290,7 @@  next_array_record (st_parameter_dt *dtp, array_loop_spec *ls, int *finished)
    position.  */
 
 static void
-skip_record (st_parameter_dt *dtp, ssize_t bytes)
+skip_record (st_parameter_dt *dtp, gfc_offset bytes)
 {
   ssize_t rlength, readb;
 #define MAX_READ 4096
@@ -3367,7 +3367,6 @@  static void
 next_record_r (st_parameter_dt *dtp, int done)
 {
   gfc_offset record;
-  int bytes_left;
   char p;
   int cc;
 
@@ -3419,7 +3418,7 @@  next_record_r (st_parameter_dt *dtp, int done)
 	    }
 	  else
 	    {
-	      bytes_left = (int) dtp->u.p.current_unit->bytes_left;
+	      gfc_offset bytes_left = dtp->u.p.current_unit->bytes_left;
 	      bytes_left = min_off (bytes_left,
 		      ssize (dtp->u.p.current_unit->s)
 		      - stell (dtp->u.p.current_unit->s));
@@ -3590,12 +3589,13 @@  next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
 /* Utility function like memset() but operating on streams. Return
    value is same as for POSIX write().  */
 
-static ssize_t
-sset (stream *s, int c, ssize_t nbyte)
+static gfc_offset
+sset (stream *s, int c, gfc_offset nbyte)
 {
 #define WRITE_CHUNK 256
   char p[WRITE_CHUNK];
-  ssize_t bytes_left, trans;
+  gfc_offset bytes_left;
+  ssize_t trans;
 
   if (nbyte < WRITE_CHUNK)
     memset (p, c, nbyte);
@@ -3645,11 +3645,10 @@  next_record_cc (st_parameter_dt *dtp)
 static void
 next_record_w (st_parameter_dt *dtp, int done)
 {
-  gfc_offset m, record, max_pos;
-  int length;
+  gfc_offset max_pos_off;
 
   /* Zero counters for X- and T-editing.  */
-  max_pos = dtp->u.p.max_pos;
+  max_pos_off = dtp->u.p.max_pos;
   dtp->u.p.max_pos = dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
 
   switch (current_mode (dtp))
@@ -3674,7 +3673,7 @@  next_record_w (st_parameter_dt *dtp, int done)
     case UNFORMATTED_DIRECT:
       if (dtp->u.p.current_unit->bytes_left > 0)
 	{
-	  length = (int) dtp->u.p.current_unit->bytes_left;
+	  gfc_offset length = dtp->u.p.current_unit->bytes_left;
 	  if (sset (dtp->u.p.current_unit->s, 0, length) != length)
 	    goto io_error;
 	}
@@ -3691,11 +3690,14 @@  next_record_w (st_parameter_dt *dtp, int done)
       if (is_internal_unit (dtp))
 	{
 	  char *p;
+	  /* Internal unit, so must fit in memory.  */
+	  ptrdiff_t length, m, record;
+	  ptrdiff_t max_pos = max_pos_off;
 	  if (is_array_io (dtp))
 	    {
 	      int finished;
 
-	      length = (int) dtp->u.p.current_unit->bytes_left;
+	      length = dtp->u.p.current_unit->bytes_left;
 
 	      /* If the farthest position reached is greater than current
 	      position, adjust the position and set length to pad out
@@ -3705,14 +3707,14 @@  next_record_w (st_parameter_dt *dtp, int done)
 			- dtp->u.p.current_unit->bytes_left;
 	      if (max_pos > m)
 		{
-		  length = (int) (max_pos - m);
+		  length = (max_pos - m);
 		  if (sseek (dtp->u.p.current_unit->s,
 			     length, SEEK_CUR) < 0)
 		    {
 		      generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
 		      return;
 		    }
-		  length = (int) (dtp->u.p.current_unit->recl - max_pos);
+		  length = ((ptrdiff_t) dtp->u.p.current_unit->recl - max_pos);
 		}
 
 	      p = write_block (dtp, length);
@@ -3735,7 +3737,7 @@  next_record_w (st_parameter_dt *dtp, int done)
 		dtp->u.p.current_unit->endfile = AT_ENDFILE;
 
 	      /* Now seek to this record */
-	      record = record * dtp->u.p.current_unit->recl;
+	      record = record * ((ptrdiff_t) dtp->u.p.current_unit->recl);
 
 	      if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
 		{
@@ -3758,17 +3760,18 @@  next_record_w (st_parameter_dt *dtp, int done)
 			- dtp->u.p.current_unit->bytes_left;
 		  if (max_pos > m)
 		    {
-		      length = (int) (max_pos - m);
+		      length = max_pos - m;
 		      if (sseek (dtp->u.p.current_unit->s,
 				 length, SEEK_CUR) < 0)
 		        {
 			  generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
 			  return;
 			}
-		      length = (int) (dtp->u.p.current_unit->recl - max_pos);
+		      length = (ptrdiff_t) dtp->u.p.current_unit->recl
+			- max_pos;
 		    }
 		  else
-		    length = (int) dtp->u.p.current_unit->bytes_left;
+		    length = dtp->u.p.current_unit->bytes_left;
 		}
 	      if (length > 0)
 		{