PR 78534, 83704 Handle large formatted I/O

Message ID 1515320295-27028-1-git-send-email-blomqvist.janne@gmail.com
State New
Headers show
Series
  • PR 78534, 83704 Handle large formatted I/O
Related show

Commit Message

Janne Blomqvist Jan. 7, 2018, 10:18 a.m.
In order to handle large characters when doing formatted I/O, use
size_t and ptrdiff_t for lengths.  Compared to the previous patch,
based on discussions on IRC use size_t for sizes that don't need to be
negative rather than ptrdiff_t everywhere.

Regtested on x86_64-pc-linux-gnu, approved as part of the PR 78534
approval, committed to trunk.

libgfortran/ChangeLog:

2018-01-07  Janne Blomqvist  <jb@gcc.gnu.org>

	PR fortran/78534
	PR fortran/83704
	* io/fbuf.c (fbuf_init): Use size_t instead of int for length.
	(fbuf_debug): Convert debug output to unsigned long.
	(fbuf_reset): Use ptrdiff_t for return value.
	(fbuf_alloc): Use size_t for length argument.
	(fbuf_flush): Handle large buffers.
	(fbuf_flush_list): Likewise.
	(fbuf_seek): Use ptrdiff_t for offset and return value.
	(fbuf_read): Use size_t for length argument.
	(fbuf_getc_refill): Use size_t to match fbuf_read.
	* io/fbuf.h (struct fbuf): Use size_t for lengths.
	(fbuf_init): Use size_t instead of int for length.
	(fbuf_reset): Use ptrdiff_t for return value.
	(fbuf_alloc): Use size_t for length argument.
	(fbuf_seek): Use ptrdiff_t for offset and return value.
	(fbuf_read): Use size_t for length argument.
	* io/io.h (read_block_form): Likewise.
	(read_block_form4): Likewise.
	(write_block): Likewise.
	(read_a): Likewise.
	(read_a_char4): Likewise.
	(read_x): Likewise.
	(write_a): Likewise.
	(write_a_char4): Likewise.
	* io/list_read.c (list_formatted_read_scalar): Use size_t to
	handle large buffers.
	* io/read.c (read_l): Likewise.
	(read_utf8): Likewise.
	(read_utf8_char1): Likewise.
	(read_default_char1): Likewise.
	(read_utf8_char4): Likewise.
	(read_default_char4): Likewise.
	(read_a): Likewise.
	(read_a_char4): Likewise.
	(eat_leading_spaces): Likewise.
	(next_char): Likewise.
	(read_decimal): Likewise.
	(read_radix): Likewise.
	(read_f): Likewise.
	(read_x): Likewise.
	* io/transfer.c (read_sf_internal): Likewise.
	(read_sf): Likewise.
	(read_block_form): Likewise.
	(read_block_form4): Likewise.
	(write_block): Likewise.
	(formatted_transfer_scalar_write): Likewise.
	(next_record_w): Likewise.
	* io/unix.c (mem_alloc_r): Likewise.
	(mem_alloc_r4): Likewise.
	(mem_alloc_w): Likewise.
	(mem_alloc_w4): Likewise.
	(mem_read): Likewise.
	(mem_read4): Likewise.
	(mem_write): Likewise.
	(mem_write4): Likewise.
	(open_internal): Likewise.
	(open_internal4): Likewise.
	* io/unix.h (open_internal): Likewise.
	(open_internal4): Likewise.
	(mem_alloc_w): Likewise.
	(mem_alloc_r): Likewise.
	(mem_alloc_w4): Likewise.
	(mem_alloc_r4): Likewise.
	* io/write.c (write_check_cc): Likewise.
	(write_cc): Likewise.
	(write_a): Likewise.
	(write_a_char4): Likewise.
---
 libgfortran/io/fbuf.c      | 52 ++++++++++++-------------
 libgfortran/io/fbuf.h      | 16 ++++----
 libgfortran/io/io.h        | 16 ++++----
 libgfortran/io/list_read.c | 15 ++++----
 libgfortran/io/read.c      | 95 +++++++++++++++++++++++++---------------------
 libgfortran/io/transfer.c  | 46 +++++++++++-----------
 libgfortran/io/unix.c      | 24 ++++++------
 libgfortran/io/unix.h      | 12 +++---
 libgfortran/io/write.c     | 25 ++++++------
 9 files changed, 153 insertions(+), 148 deletions(-)

-- 
2.7.4

Patch

diff --git a/libgfortran/io/fbuf.c b/libgfortran/io/fbuf.c
index aa463f1..7ff9f09 100644
--- a/libgfortran/io/fbuf.c
+++ b/libgfortran/io/fbuf.c
@@ -33,7 +33,7 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 
 void
-fbuf_init (gfc_unit *u, int len)
+fbuf_init (gfc_unit *u, size_t len)
 {
   if (len == 0)
     len = 512;			/* Default size.  */
@@ -64,9 +64,9 @@  fbuf_debug (gfc_unit *u, const char *format, ...)
   va_start(args, format);
   vfprintf(stderr, format, args);
   va_end(args);
-  fprintf (stderr, "fbuf_debug pos: %d, act: %d, buf: ''", 
-           u->fbuf->pos, u->fbuf->act);
-  for (int ii = 0; ii < u->fbuf->act; ii++)
+  fprintf (stderr, "fbuf_debug pos: %lu, act: %lu, buf: ''",
+           (long unsigned) u->fbuf->pos, (long unsigned) u->fbuf->act);
+  for (size_t ii = 0; ii < u->fbuf->act; ii++)
     {
       putc (u->fbuf->buf[ii], stderr);
     }
@@ -84,10 +84,10 @@  fbuf_debug (gfc_unit *u __attribute__ ((unused)),
    underlying device.  Returns how much the physical position was
    modified.  */
 
-int
+ptrdiff_t
 fbuf_reset (gfc_unit *u)
 {
-  int seekval = 0;
+  ptrdiff_t seekval = 0;
 
   if (!u->fbuf)
     return 0;
@@ -99,7 +99,7 @@  fbuf_reset (gfc_unit *u)
   if (u->mode == READING && u->fbuf->act > u->fbuf->pos)
     {
       seekval = - (u->fbuf->act - u->fbuf->pos);
-      fbuf_debug (u, "fbuf_reset seekval %d, ", seekval);
+      fbuf_debug (u, "fbuf_reset seekval %ld, ", (long) seekval);
     }
   u->fbuf->act = u->fbuf->pos = 0;
   return seekval;
@@ -111,11 +111,11 @@  fbuf_reset (gfc_unit *u)
    reallocating if necessary.  */
 
 char *
-fbuf_alloc (gfc_unit *u, int len)
+fbuf_alloc (gfc_unit *u, size_t len)
 {
-  int newlen;
+  size_t newlen;
   char *dest;
-  fbuf_debug (u, "fbuf_alloc len %d, ", len);
+  fbuf_debug (u, "fbuf_alloc len %lu, ", (long unsigned) len);
   if (u->fbuf->pos + len > u->fbuf->len)
     {
       /* Round up to nearest multiple of the current buffer length.  */
@@ -138,8 +138,6 @@  fbuf_alloc (gfc_unit *u, int len)
 int
 fbuf_flush (gfc_unit *u, unit_mode mode)
 {
-  int nwritten;
-
   if (!u->fbuf)
     return 0;
 
@@ -149,7 +147,7 @@  fbuf_flush (gfc_unit *u, unit_mode mode)
     {
       if (u->fbuf->pos > 0)
 	{
-	  nwritten = swrite (u->s, u->fbuf->buf, u->fbuf->pos);
+	  ptrdiff_t nwritten = swrite (u->s, u->fbuf->buf, u->fbuf->pos);
 	  if (nwritten < 0)
 	    return -1;
 	}
@@ -177,8 +175,6 @@  fbuf_flush (gfc_unit *u, unit_mode mode)
 int
 fbuf_flush_list (gfc_unit *u, unit_mode mode)
 {
-  int nwritten;
-
   if (!u->fbuf)
     return 0;
 
@@ -189,7 +185,7 @@  fbuf_flush_list (gfc_unit *u, unit_mode mode)
 
   if (mode == LIST_WRITING)
     {
-      nwritten = swrite (u->s, u->fbuf->buf, u->fbuf->pos);
+      ptrdiff_t nwritten = swrite (u->s, u->fbuf->buf, u->fbuf->pos);
       if (nwritten < 0)
 	return -1;
     }
@@ -206,8 +202,8 @@  fbuf_flush_list (gfc_unit *u, unit_mode mode)
 }
 
 
-int
-fbuf_seek (gfc_unit *u, int off, int whence)
+ptrdiff_t
+fbuf_seek (gfc_unit *u, ptrdiff_t off, int whence)
 {
   if (!u->fbuf)
     return -1;
@@ -226,7 +222,7 @@  fbuf_seek (gfc_unit *u, int off, int whence)
       return -1;
     }
 
-  fbuf_debug (u, "fbuf_seek, off %d ", off);
+  fbuf_debug (u, "fbuf_seek, off %ld ", (long) off);
   /* The start of the buffer is always equal to the left tab
      limit. Moving to the left past the buffer is illegal in C and
      would also imply moving past the left tab limit, which is never
@@ -234,7 +230,7 @@  fbuf_seek (gfc_unit *u, int off, int whence)
      is not possible, in that case the user must make sure to allocate
      space with fbuf_alloc().  So return error if that is
      attempted.  */
-  if (off < 0 || off > u->fbuf->act)
+  if (off < 0 || off > (ptrdiff_t) u->fbuf->act)
     return -1;
   u->fbuf->pos = off;
   return off;
@@ -248,21 +244,22 @@  fbuf_seek (gfc_unit *u, int off, int whence)
    of bytes actually processed. */
 
 char *
-fbuf_read (gfc_unit *u, int *len)
+fbuf_read (gfc_unit *u, size_t *len)
 {
   char *ptr;
-  int oldact, oldpos;
-  int readlen = 0;
+  size_t oldact, oldpos;
+  ptrdiff_t readlen = 0;
 
-  fbuf_debug (u, "fbuf_read, len %d: ", *len);
+  fbuf_debug (u, "fbuf_read, len %lu: ", (unsigned long) *len);
   oldact = u->fbuf->act;
   oldpos = u->fbuf->pos;
   ptr = fbuf_alloc (u, *len);
   u->fbuf->pos = oldpos;
   if (oldpos + *len > oldact)
     {
-      fbuf_debug (u, "reading %d bytes starting at %d ", 
-                  oldpos + *len - oldact, oldact);
+      fbuf_debug (u, "reading %lu bytes starting at %lu ",
+                  (long unsigned) oldpos + *len - oldact,
+		  (long unsigned) oldact);
       readlen = sread (u->s, u->fbuf->buf + oldact, oldpos + *len - oldact);
       if (readlen < 0)
 	return NULL;
@@ -281,7 +278,6 @@  fbuf_read (gfc_unit *u, int *len)
 int
 fbuf_getc_refill (gfc_unit *u)
 {
-  int nread;
   char *p;
 
   fbuf_debug (u, "fbuf_getc_refill ");
@@ -290,7 +286,7 @@  fbuf_getc_refill (gfc_unit *u)
      between not needing to call the read() syscall all the time and
      not having to memmove unnecessary stuff when switching to the
      next record.  */
-  nread = 80;
+  size_t nread = 80;
 
   p = fbuf_read (u, &nread);
 
diff --git a/libgfortran/io/fbuf.h b/libgfortran/io/fbuf.h
index 8dd94db..71b6d0f 100644
--- a/libgfortran/io/fbuf.h
+++ b/libgfortran/io/fbuf.h
@@ -39,21 +39,21 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 struct fbuf
 {
   char *buf;			/* Start of buffer.  */
-  int len;			/* Length of buffer.  */
-  int act;			/* Active bytes in buffer.  */
-  int pos;			/* Current position in buffer.  */
+  size_t len;			/* Length of buffer.  */
+  size_t act;			/* Active bytes in buffer.  */
+  size_t pos;			/* Current position in buffer.  */
 };
 
-extern void fbuf_init (gfc_unit *, int);
+extern void fbuf_init (gfc_unit *, size_t);
 internal_proto(fbuf_init);
 
 extern void fbuf_destroy (gfc_unit *);
 internal_proto(fbuf_destroy);
 
-extern int fbuf_reset (gfc_unit *);
+extern ptrdiff_t fbuf_reset (gfc_unit *);
 internal_proto(fbuf_reset);
 
-extern char *fbuf_alloc (gfc_unit *, int);
+extern char *fbuf_alloc (gfc_unit *, size_t);
 internal_proto(fbuf_alloc);
 
 extern int fbuf_flush (gfc_unit *, unit_mode);
@@ -62,10 +62,10 @@  internal_proto(fbuf_flush);
 extern int fbuf_flush_list (gfc_unit *, unit_mode);
 internal_proto(fbuf_flush_list);
 
-extern int fbuf_seek (gfc_unit *, int, int);
+extern ptrdiff_t fbuf_seek (gfc_unit *, ptrdiff_t, int);
 internal_proto(fbuf_seek);
 
-extern char *fbuf_read (gfc_unit *, int *);
+extern char *fbuf_read (gfc_unit *, size_t *);
 internal_proto(fbuf_read);
 
 /* Never call this function, only use fbuf_getc().  */
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h
index b32fcd3..3c2a2ca 100644
--- a/libgfortran/io/io.h
+++ b/libgfortran/io/io.h
@@ -794,13 +794,13 @@  internal_proto(new_unit);
 extern const char *type_name (bt);
 internal_proto(type_name);
 
-extern void * read_block_form (st_parameter_dt *, int *);
+extern void * read_block_form (st_parameter_dt *, size_t *);
 internal_proto(read_block_form);
 
-extern void * read_block_form4 (st_parameter_dt *, int *);
+extern void * read_block_form4 (st_parameter_dt *, size_t *);
 internal_proto(read_block_form4);
 
-extern void *write_block (st_parameter_dt *, int);
+extern void *write_block (st_parameter_dt *, size_t);
 internal_proto(write_block);
 
 extern gfc_offset next_array_record (st_parameter_dt *, array_loop_spec *,
@@ -834,10 +834,10 @@  internal_proto(convert_real);
 extern int convert_infnan (st_parameter_dt *, void *, const char *, int);
 internal_proto(convert_infnan);
 
-extern void read_a (st_parameter_dt *, const fnode *, char *, int);
+extern void read_a (st_parameter_dt *, const fnode *, char *, size_t);
 internal_proto(read_a);
 
-extern void read_a_char4 (st_parameter_dt *, const fnode *, char *, int);
+extern void read_a_char4 (st_parameter_dt *, const fnode *, char *, size_t);
 internal_proto(read_a);
 
 extern void read_f (st_parameter_dt *, const fnode *, char *, int);
@@ -846,7 +846,7 @@  internal_proto(read_f);
 extern void read_l (st_parameter_dt *, const fnode *, char *, int);
 internal_proto(read_l);
 
-extern void read_x (st_parameter_dt *, int);
+extern void read_x (st_parameter_dt *, size_t);
 internal_proto(read_x);
 
 extern void read_radix (st_parameter_dt *, const fnode *, char *, int, int);
@@ -878,10 +878,10 @@  internal_proto(namelist_write);
 
 /* write.c */
 
-extern void write_a (st_parameter_dt *, const fnode *, const char *, int);
+extern void write_a (st_parameter_dt *, const fnode *, const char *, size_t);
 internal_proto(write_a);
 
-extern void write_a_char4 (st_parameter_dt *, const fnode *, const char *, int);
+extern void write_a_char4 (st_parameter_dt *, const fnode *, const char *, size_t);
 internal_proto(write_a_char4);
 
 extern void write_b (st_parameter_dt *, const fnode *, const char *, int);
diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c
index 62c215c..fbd7dc2 100644
--- a/libgfortran/io/list_read.c
+++ b/libgfortran/io/list_read.c
@@ -2100,7 +2100,8 @@  list_formatted_read_scalar (st_parameter_dt *dtp, bt type, void *p,
 			    int kind, size_t size)
 {
   gfc_char4_t *q, *r;
-  int c, i, m;
+  size_t m;
+  int c;
   int err = 0;
 
   /* Set the next_char and push_char worker functions.  */
@@ -2255,20 +2256,20 @@  list_formatted_read_scalar (st_parameter_dt *dtp, bt type, void *p,
     case BT_CHARACTER:
       if (dtp->u.p.saved_string)
 	{
-	  m = ((int) size < dtp->u.p.saved_used)
-	      ? (int) size : dtp->u.p.saved_used;
+	  m = (size < (size_t) dtp->u.p.saved_used)
+	    ? size : (size_t) dtp->u.p.saved_used;
 
 	  q = (gfc_char4_t *) p;
 	  r = (gfc_char4_t *) dtp->u.p.saved_string;
 	  if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
-	    for (i = 0; i < m; i++)
+	    for (size_t i = 0; i < m; i++)
 	      *q++ = *r++;
 	  else
 	    {
 	      if (kind == 1)
 		memcpy (p, dtp->u.p.saved_string, m);
 	      else
-		for (i = 0; i < m; i++)
+		for (size_t i = 0; i < m; i++)
 		  *q++ = *r++;
 	    }
 	}
@@ -2276,14 +2277,14 @@  list_formatted_read_scalar (st_parameter_dt *dtp, bt type, void *p,
 	/* Just delimiters encountered, nothing to copy but SPACE.  */
         m = 0;
 
-      if (m < (int) size)
+      if (m < size)
 	{
 	  if (kind == 1)
 	    memset (((char *) p) + m, ' ', size - m);
 	  else
 	    {
 	      q = (gfc_char4_t *) p;
-	      for (i = m; i < (int) size; i++)
+	      for (size_t i = m; i < size; i++)
 		q[i] = (unsigned char) ' ';
 	    }
 	}
diff --git a/libgfortran/io/read.c b/libgfortran/io/read.c
index 167587f..87adfb8 100644
--- a/libgfortran/io/read.c
+++ b/libgfortran/io/read.c
@@ -272,7 +272,7 @@  void
 read_l (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
 {
   char *p;
-  int w;
+  size_t w;
 
   w = f->u.w;
 
@@ -316,11 +316,11 @@  read_l (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
 
 
 static gfc_char4_t
-read_utf8 (st_parameter_dt *dtp, int *nbytes) 
+read_utf8 (st_parameter_dt *dtp, size_t *nbytes)
 {
   static const uchar masks[6] = { 0x7F, 0x1F, 0x0F, 0x07, 0x02, 0x01 };
   static const uchar patns[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
-  int i, nb, nread;
+  size_t nb, nread;
   gfc_char4_t c;
   char *s;
 
@@ -353,7 +353,7 @@  read_utf8 (st_parameter_dt *dtp, int *nbytes)
   if (s == NULL)
     return 0;
   /* Decode the bytes read.  */
-  for (i = 1; i < nb; i++)
+  for (size_t i = 1; i < nb; i++)
     {
       gfc_char4_t n = *s++;
 
@@ -383,12 +383,11 @@  read_utf8 (st_parameter_dt *dtp, int *nbytes)
 
 
 static void
-read_utf8_char1 (st_parameter_dt *dtp, char *p, int len, int width)
+read_utf8_char1 (st_parameter_dt *dtp, char *p, size_t len, size_t width)
 {
   gfc_char4_t c;
   char *dest;
-  int nbytes;
-  int i, j;
+  size_t nbytes, j;
 
   len = (width < len) ? len : width;
 
@@ -407,16 +406,16 @@  read_utf8_char1 (st_parameter_dt *dtp, char *p, int len, int width)
     }
 
   /* If there was a short read, pad the remaining characters.  */
-  for (i = j; i < len; i++)
+  for (size_t i = j; i < len; i++)
     *dest++ = ' ';
   return;
 }
 
 static void
-read_default_char1 (st_parameter_dt *dtp, char *p, int len, int width)
+read_default_char1 (st_parameter_dt *dtp, char *p, size_t len, size_t width)
 {
   char *s;
-  int m, n;
+  size_t m;
 
   s = read_block_form (dtp, &width);
   
@@ -428,18 +427,16 @@  read_default_char1 (st_parameter_dt *dtp, char *p, int len, int width)
   m = (width > len) ? len : width;
   memcpy (p, s, m);
 
-  n = len - width;
-  if (n > 0)
-    memset (p + m, ' ', n);
+  if (len > width)
+    memset (p + m, ' ', len - width);
 }
 
 
 static void
-read_utf8_char4 (st_parameter_dt *dtp, void *p, int len, int width)
+read_utf8_char4 (st_parameter_dt *dtp, void *p, size_t len, size_t width)
 {
   gfc_char4_t *dest;
-  int nbytes;
-  int i, j;
+  size_t nbytes, j;
 
   len = (width < len) ? len : width;
 
@@ -456,16 +453,16 @@  read_utf8_char4 (st_parameter_dt *dtp, void *p, int len, int width)
     }
 
   /* If there was a short read, pad the remaining characters.  */
-  for (i = j; i < len; i++)
+  for (size_t i = j; i < len; i++)
     *dest++ = (gfc_char4_t) ' ';
   return;
 }
 
 
 static void
-read_default_char4 (st_parameter_dt *dtp, char *p, int len, int width)
+read_default_char4 (st_parameter_dt *dtp, char *p, size_t len, size_t width)
 {
-  int m, n;
+  size_t m, n;
   gfc_char4_t *dest;
 
   if (is_char4_unit(dtp))
@@ -479,15 +476,18 @@  read_default_char4 (st_parameter_dt *dtp, char *p, int len, int width)
       if (width > len)
 	 s4 += (width - len);
 
-      m = ((int) width > len) ? len : (int) width;
+      m = (width > len) ? len : width;
 
       dest = (gfc_char4_t *) p;
 
       for (n = 0; n < m; n++)
 	*dest++ = *s4++;
 
-      for (n = 0; n < len - (int) width; n++)
-	*dest++ = (gfc_char4_t) ' ';
+      if (len > width)
+	{
+	  for (n = 0; n < len - width; n++)
+	    *dest++ = (gfc_char4_t) ' ';
+	}
     }
   else
     {
@@ -500,15 +500,18 @@  read_default_char4 (st_parameter_dt *dtp, char *p, int len, int width)
       if (width > len)
 	 s += (width - len);
 
-      m = ((int) width > len) ? len : (int) width;
+      m = (width > len) ? len : width;
 
       dest = (gfc_char4_t *) p;
 
       for (n = 0; n < m; n++, dest++, s++)
 	*dest = (unsigned char ) *s;
 
-      for (n = 0; n < len - (int) width; n++, dest++)
-	*dest = (unsigned char) ' ';
+      if (len > width)
+	{
+	  for (n = 0; n < len - width; n++, dest++)
+	    *dest = (unsigned char) ' ';
+	}
     }
 }
 
@@ -517,15 +520,14 @@  read_default_char4 (st_parameter_dt *dtp, char *p, int len, int width)
    processing UTF-8 encoding if necessary.  */
 
 void
-read_a (st_parameter_dt *dtp, const fnode *f, char *p, int length)
+read_a (st_parameter_dt *dtp, const fnode *f, char *p, size_t length)
 {
-  int wi;
-  int w;
+  size_t w;
 
-  wi = f->u.w;
-  if (wi == -1) /* '(A)' edit descriptor  */
-    wi = length;
-  w = wi;
+  if (f->u.w == -1) /* '(A)' edit descriptor  */
+    w = length;
+  else
+    w = f->u.w;
 
   /* Read in w characters, treating comma as not a separator.  */
   dtp->u.p.sf_read_comma = 0;
@@ -544,13 +546,14 @@  read_a (st_parameter_dt *dtp, const fnode *f, char *p, int length)
    processing UTF-8 encoding if necessary.  */
 
 void
-read_a_char4 (st_parameter_dt *dtp, const fnode *f, char *p, int length)
+read_a_char4 (st_parameter_dt *dtp, const fnode *f, char *p, size_t length)
 {
-  int w;
+  size_t w;
 
-  w = f->u.w;
-  if (w == -1) /* '(A)' edit descriptor  */
+  if (f->u.w == -1) /* '(A)' edit descriptor  */
     w = length;
+  else
+    w = f->u.w;
 
   /* Read in w characters, treating comma as not a separator.  */
   dtp->u.p.sf_read_comma = 0;
@@ -568,7 +571,7 @@  read_a_char4 (st_parameter_dt *dtp, const fnode *f, char *p, int length)
    ignore the leading spaces.  */
 
 static char *
-eat_leading_spaces (int *width, char *p)
+eat_leading_spaces (size_t *width, char *p)
 {
   for (;;)
     {
@@ -584,7 +587,7 @@  eat_leading_spaces (int *width, char *p)
 
 
 static char
-next_char (st_parameter_dt *dtp, char **p, int *w)
+next_char (st_parameter_dt *dtp, char **p, size_t *w)
 {
   char c, *q;
 
@@ -624,7 +627,8 @@  read_decimal (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
 {
   GFC_UINTEGER_LARGEST value, maxv, maxv_10;
   GFC_INTEGER_LARGEST v;
-  int w, negative; 
+  size_t w;
+  int negative;
   char c, *p;
 
   w = f->u.w;
@@ -732,7 +736,8 @@  read_radix (st_parameter_dt *dtp, const fnode *f, char *dest, int length,
 {
   GFC_UINTEGER_LARGEST value, maxv, maxv_r;
   GFC_INTEGER_LARGEST v;
-  int w, negative;
+  size_t w;
+  int negative;
   char c, *p;
 
   w = f->u.w;
@@ -882,7 +887,8 @@  read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
 #define READF_TMP 50
   char tmp[READF_TMP];
   size_t buf_size = 0;
-  int w, seen_dp, exponent;
+  size_t w;
+  int seen_dp, exponent;
   int exponent_sign;
   const char *p;
   char *buffer;
@@ -1230,12 +1236,13 @@  bad_float:
    and never look at it. */
 
 void
-read_x (st_parameter_dt *dtp, int n)
+read_x (st_parameter_dt *dtp, size_t n)
 {
-  int length, q, q2;
+  size_t length;
+  int q, q2;
 
   if ((dtp->u.p.current_unit->pad_status == PAD_NO || is_internal_unit (dtp))
-       && dtp->u.p.current_unit->bytes_left < n)
+      && dtp->u.p.current_unit->bytes_left < (gfc_offset) n)
     n = dtp->u.p.current_unit->bytes_left;
     
   if (n == 0)
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index 4aafcd0..f9c8696 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -223,11 +223,11 @@  current_mode (st_parameter_dt *dtp)
 /* Read sequential file - internal unit  */
 
 static char *
-read_sf_internal (st_parameter_dt *dtp, int *length)
+read_sf_internal (st_parameter_dt *dtp, size_t *length)
 {
   static char *empty_string[0];
   char *base = NULL;
-  int lorig;
+  size_t lorig;
 
   /* Zero size array gives internal unit len of 0.  Nothing to read. */
   if (dtp->internal_unit_len == 0
@@ -256,11 +256,10 @@  read_sf_internal (st_parameter_dt *dtp, int *length)
   lorig = *length;
   if (is_char4_unit(dtp))
     {
-      int i;
       gfc_char4_t *p = (gfc_char4_t *) mem_alloc_r4 (dtp->u.p.current_unit->s,
 			length);
       base = fbuf_alloc (dtp->u.p.current_unit, lorig);
-      for (i = 0; i < *length; i++, p++)
+      for (size_t i = 0; i < *length; i++, p++)
 	base[i] = *p > 255 ? '?' : (unsigned char) *p;
     }
   else
@@ -297,11 +296,12 @@  read_sf_internal (st_parameter_dt *dtp, int *length)
 /* Read sequential file - external unit */
 
 static char *
-read_sf (st_parameter_dt *dtp, int *length)
+read_sf (st_parameter_dt *dtp, size_t *length)
 {
   static char *empty_string[0];
+  size_t lorig, n;
   int q, q2;
-  int n, lorig, seen_comma;
+  int seen_comma;
 
   /* If we have seen an eor previously, return a length of 0.  The
      caller is responsible for correctly padding the input field.  */
@@ -439,10 +439,10 @@  read_sf (st_parameter_dt *dtp, int *length)
    short reads.  */
 
 void *
-read_block_form (st_parameter_dt *dtp, int *nbytes)
+read_block_form (st_parameter_dt *dtp, size_t *nbytes)
 {
   char *source;
-  int norig;
+  size_t norig;
 
   if (!is_stream_io (dtp))
     {
@@ -534,11 +534,11 @@  read_block_form (st_parameter_dt *dtp, int *nbytes)
    a character(kind=4) variable.  Note: Portions of this code borrowed from
    read_sf_internal.  */
 void *
-read_block_form4 (st_parameter_dt *dtp, int *nbytes)
+read_block_form4 (st_parameter_dt *dtp, size_t *nbytes)
 {
   static gfc_char4_t *empty_string[0];
   gfc_char4_t *source;
-  int lorig;
+  size_t lorig;
 
   if (dtp->u.p.current_unit->bytes_left < (gfc_offset) *nbytes)
     *nbytes = dtp->u.p.current_unit->bytes_left;
@@ -743,7 +743,7 @@  read_block_direct (st_parameter_dt *dtp, void *buf, size_t nbytes)
    fill in.  Returns NULL on error.  */
 
 void *
-write_block (st_parameter_dt *dtp, int length)
+write_block (st_parameter_dt *dtp, size_t length)
 {
   char *dest;
 
@@ -1792,7 +1792,7 @@  static void
 formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kind,
 				 size_t size)
 {
-  int pos, bytes_used;
+  gfc_offset pos, bytes_used;
   const fnode *f;
   format_token t;
   int n;
@@ -1856,10 +1856,10 @@  formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kin
 	{
 	  if (dtp->u.p.skips > 0)
 	    {
-	      int tmp;
+	      gfc_offset tmp;
 	      write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
-	      tmp = (int)(dtp->u.p.current_unit->recl
-			  - dtp->u.p.current_unit->bytes_left);
+	      tmp = dtp->u.p.current_unit->recl
+			  - dtp->u.p.current_unit->bytes_left;
 	      dtp->u.p.max_pos =
 		dtp->u.p.max_pos > tmp ? dtp->u.p.max_pos : tmp;
 	      dtp->u.p.skips = 0;
@@ -1875,8 +1875,8 @@  formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kin
 	  dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
 	}
 
-      bytes_used = (int)(dtp->u.p.current_unit->recl
-		   - dtp->u.p.current_unit->bytes_left);
+      bytes_used = dtp->u.p.current_unit->recl
+		   - dtp->u.p.current_unit->bytes_left;
 
       if (is_stream_io(dtp))
 	bytes_used = 0;
@@ -2231,7 +2231,7 @@  formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kin
 	  p = ((char *) p) + size;
 	}
 
-      pos = (int)(dtp->u.p.current_unit->recl - dtp->u.p.current_unit->bytes_left);
+      pos = dtp->u.p.current_unit->recl - dtp->u.p.current_unit->bytes_left;
       dtp->u.p.max_pos = (dtp->u.p.max_pos > pos) ? dtp->u.p.max_pos : pos;
     }
 
@@ -3691,8 +3691,8 @@  next_record_w (st_parameter_dt *dtp, int done)
 	{
 	  char *p;
 	  /* Internal unit, so must fit in memory.  */
-	  ptrdiff_t length, m, record;
-	  ptrdiff_t max_pos = max_pos_off;
+	  size_t length, m, record;
+	  size_t max_pos = max_pos_off;
 	  if (is_array_io (dtp))
 	    {
 	      int finished;
@@ -3714,7 +3714,7 @@  next_record_w (st_parameter_dt *dtp, int done)
 		      generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
 		      return;
 		    }
-		  length = ((ptrdiff_t) dtp->u.p.current_unit->recl - max_pos);
+		  length = ((size_t) dtp->u.p.current_unit->recl - max_pos);
 		}
 
 	      p = write_block (dtp, length);
@@ -3737,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 * ((ptrdiff_t) dtp->u.p.current_unit->recl);
+	      record = record * ((size_t) dtp->u.p.current_unit->recl);
 
 	      if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
 		{
@@ -3767,7 +3767,7 @@  next_record_w (st_parameter_dt *dtp, int done)
 			  generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
 			  return;
 			}
-		      length = (ptrdiff_t) dtp->u.p.current_unit->recl
+		      length = (size_t) dtp->u.p.current_unit->recl
 			- max_pos;
 		    }
 		  else
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index 822d34f..a8fd07a 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -776,7 +776,7 @@  buf_init (unix_stream *s)
 *********************************************************************/
 
 char *
-mem_alloc_r (stream *strm, int *len)
+mem_alloc_r (stream *strm, size_t *len)
 {
   unix_stream *s = (unix_stream *) strm;
   gfc_offset n;
@@ -786,7 +786,7 @@  mem_alloc_r (stream *strm, int *len)
     return NULL;
 
   n = s->buffer_offset + s->active - where;
-  if (*len > n)
+  if ((gfc_offset) *len > n)
     *len = n;
 
   s->logical_offset = where + *len;
@@ -796,7 +796,7 @@  mem_alloc_r (stream *strm, int *len)
 
 
 char *
-mem_alloc_r4 (stream *strm, int *len)
+mem_alloc_r4 (stream *strm, size_t *len)
 {
   unix_stream *s = (unix_stream *) strm;
   gfc_offset n;
@@ -806,7 +806,7 @@  mem_alloc_r4 (stream *strm, int *len)
     return NULL;
 
   n = s->buffer_offset + s->active - where;
-  if (*len > n)
+  if ((gfc_offset) *len > n)
     *len = n;
 
   s->logical_offset = where + *len;
@@ -816,7 +816,7 @@  mem_alloc_r4 (stream *strm, int *len)
 
 
 char *
-mem_alloc_w (stream *strm, int *len)
+mem_alloc_w (stream *strm, size_t *len)
 {
   unix_stream *s = (unix_stream *)strm;
   gfc_offset m;
@@ -837,7 +837,7 @@  mem_alloc_w (stream *strm, int *len)
 
 
 gfc_char4_t *
-mem_alloc_w4 (stream *strm, int *len)
+mem_alloc_w4 (stream *strm, size_t *len)
 {
   unix_stream *s = (unix_stream *)strm;
   gfc_offset m;
@@ -863,7 +863,7 @@  static ssize_t
 mem_read (stream *s, void *buf, ssize_t nbytes)
 {
   void *p;
-  int nb = nbytes;
+  size_t nb = nbytes;
 
   p = mem_alloc_r (s, &nb);
   if (p)
@@ -882,7 +882,7 @@  static ssize_t
 mem_read4 (stream *s, void *buf, ssize_t nbytes)
 {
   void *p;
-  int nb = nbytes;
+  size_t nb = nbytes;
 
   p = mem_alloc_r4 (s, &nb);
   if (p)
@@ -901,7 +901,7 @@  static ssize_t
 mem_write (stream *s, const void *buf, ssize_t nbytes)
 {
   void *p;
-  int nb = nbytes;
+  size_t nb = nbytes;
 
   p = mem_alloc_w (s, &nb);
   if (p)
@@ -920,7 +920,7 @@  static ssize_t
 mem_write4 (stream *s, const void *buf, ssize_t nwords)
 {
   gfc_char4_t *p;
-  int nw = nwords;
+  size_t nw = nwords;
 
   p = mem_alloc_w4 (s, &nw);
   if (p)
@@ -1038,7 +1038,7 @@  static const struct stream_vtable mem4_vtable = {
    internal file */
 
 stream *
-open_internal (char *base, int length, gfc_offset offset)
+open_internal (char *base, size_t length, gfc_offset offset)
 {
   unix_stream *s;
 
@@ -1058,7 +1058,7 @@  open_internal (char *base, int length, gfc_offset offset)
    internal file */
 
 stream *
-open_internal4 (char *base, int length, gfc_offset offset)
+open_internal4 (char *base, size_t length, gfc_offset offset)
 {
   unix_stream *s;
 
diff --git a/libgfortran/io/unix.h b/libgfortran/io/unix.h
index 8d12631..9ad6dfa 100644
--- a/libgfortran/io/unix.h
+++ b/libgfortran/io/unix.h
@@ -108,22 +108,22 @@  internal_proto(compare_files);
 extern stream *open_external (st_parameter_open *, unit_flags *);
 internal_proto(open_external);
 
-extern stream *open_internal (char *, int, gfc_offset);
+extern stream *open_internal (char *, size_t, gfc_offset);
 internal_proto(open_internal);
 
-extern stream *open_internal4 (char *, int, gfc_offset);
+extern stream *open_internal4 (char *, size_t, gfc_offset);
 internal_proto(open_internal4);
 
-extern char *mem_alloc_w (stream *, int *);
+extern char *mem_alloc_w (stream *, size_t *);
 internal_proto(mem_alloc_w);
 
-extern char *mem_alloc_r (stream *, int *);
+extern char *mem_alloc_r (stream *, size_t *);
 internal_proto(mem_alloc_r);
 
-extern gfc_char4_t *mem_alloc_w4 (stream *, int *);
+extern gfc_char4_t *mem_alloc_w4 (stream *, size_t *);
 internal_proto(mem_alloc_w4);
 
-extern char *mem_alloc_r4 (stream *, int *);
+extern char *mem_alloc_r4 (stream *, size_t *);
 internal_proto(mem_alloc_r4);
 
 extern stream *input_stream (void);
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
index ee6b461..8021a1e 100644
--- a/libgfortran/io/write.c
+++ b/libgfortran/io/write.c
@@ -235,7 +235,7 @@  write_utf8_char4 (st_parameter_dt *dtp, gfc_char4_t *source,
    is set to the appropriate size to allocate.  */
 
 static void
-write_check_cc (st_parameter_dt *dtp, const char **source, int *alloc_len)
+write_check_cc (st_parameter_dt *dtp, const char **source, size_t *alloc_len)
 {
   /* Only valid for CARRIAGECONTROL=FORTRAN.  */
   if (dtp->u.p.current_unit->flags.cc != CC_FORTRAN
@@ -311,7 +311,7 @@  write_check_cc (st_parameter_dt *dtp, const char **source, int *alloc_len)
    after the start-of-record string was inserted.  */
 
 static char *
-write_cc (st_parameter_dt *dtp, char *p, int *source_len)
+write_cc (st_parameter_dt *dtp, char *p, size_t *source_len)
 {
   /* Only valid for CARRIAGECONTROL=FORTRAN.  */
   if (dtp->u.p.current_unit->flags.cc != CC_FORTRAN || source_len == NULL)
@@ -360,14 +360,15 @@  write_cc (st_parameter_dt *dtp, char *p, int *source_len)
 }
 
 void
-write_a (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
+
+write_a (st_parameter_dt *dtp, const fnode *f, const char *source, size_t len)
 {
-  int wlen;
+  size_t wlen;
   char *p;
 
   wlen = f->u.string.length < 0
 	 || (f->format == FMT_G && f->u.string.length == 0)
-	 ? len : f->u.string.length;
+    ? len : (size_t) f->u.string.length;
 
 #ifdef HAVE_CRLF
   /* If this is formatted STREAM IO convert any embedded line feed characters
@@ -376,7 +377,7 @@  write_a (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
   if (is_stream_io (dtp))
     {
       const char crlf[] = "\r\n";
-      int i, q, bytes;
+      size_t q, bytes;
       q = bytes = 0;
 
       /* Write out any padding if needed.  */
@@ -389,7 +390,7 @@  write_a (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
 	}
 
       /* Scan the source string looking for '\n' and convert it if found.  */
-      for (i = 0; i < wlen; i++)
+      for (size_t i = 0; i < wlen; i++)
 	{
 	  if (source[i] == '\n')
 	    {
@@ -471,14 +472,14 @@  write_a (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
    to the UTF-8 encoded string before writing out.  */
 
 void
-write_a_char4 (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
+write_a_char4 (st_parameter_dt *dtp, const fnode *f, const char *source, size_t len)
 {
-  int wlen;
+  size_t wlen;
   gfc_char4_t *q;
 
   wlen = f->u.string.length < 0
 	 || (f->format == FMT_G && f->u.string.length == 0)
-	 ? len : f->u.string.length;
+    ? len : (size_t) f->u.string.length;
 
   q = (gfc_char4_t *) source;
 #ifdef HAVE_CRLF
@@ -488,7 +489,7 @@  write_a_char4 (st_parameter_dt *dtp, const fnode *f, const char *source, int len
   if (is_stream_io (dtp))
     {
       const gfc_char4_t crlf[] = {0x000d,0x000a};
-      int i, bytes;
+      size_t bytes;
       gfc_char4_t *qq;
       bytes = 0;
 
@@ -504,7 +505,7 @@  write_a_char4 (st_parameter_dt *dtp, const fnode *f, const char *source, int len
 
       /* Scan the source string looking for '\n' and convert it if found.  */
       qq = (gfc_char4_t *) source;
-      for (i = 0; i < wlen; i++)
+      for (size_t i = 0; i < wlen; i++)
 	{
 	  if (qq[i] == '\n')
 	    {