From d57d34243215318c25a0139d971b15c9b9a1c099 Mon Sep 17 00:00:00 2001
From: Jerry DeLisle <jvdelisle@gcc.gnu.org>
Date: Fri, 31 Mar 2006 05:11:03 +0000
Subject: [PATCH] re PR libfortran/26890 (SIZE parameter interacts with same
 variable in IO list character length specification.)

2006-03-30  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libgfortran/26890
	* io/io.h: Add size_used to st_parameter_dt, adjust pad size.
	*io/transfer.c (data_transfer_init): Initialize size_used to zero.
	(read_sf): Use size_used.
	(read_block): Likewise.
	(read_block_direct): Likewise.
	(write_block): Likewise.
	(write_buf): Likewise and eliminate erroneous FAILURE return.
	(finalize_transfer): Assign value of size_used to *dtp->size.

From-SVN: r112570
---
 libgfortran/ChangeLog     | 12 ++++++++++++
 libgfortran/io/io.h       |  5 +++--
 libgfortran/io/transfer.c | 18 +++++++++---------
 3 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 4074c8c47bdc..33cfb15d0b4f 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,15 @@
+2006-03-30  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
+
+	PR libgfortran/26890
+	* io/io.h: Add size_used to st_parameter_dt, adjust pad size.
+	*io/transfer.c (data_transfer_init): Initialize size_used to zero.
+	(read_sf): Use size_used.
+	(read_block): Likewise.
+	(read_block_direct): Likewise.
+	(write_block): Likewise.
+	(write_buf): Likewise and eliminate erroneous FAILURE return.
+	(finalize_transfer): Assign value of size_used to *dtp->size.
+
 2006-03-30  Francois-Xavier Coudert  <coudert@clipper.ens.fr>
 
 	PR libfortran/26712
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h
index 1dd4a00cb649..b14576c5c0f8 100644
--- a/libgfortran/io/io.h
+++ b/libgfortran/io/io.h
@@ -412,7 +412,7 @@ typedef struct st_parameter_dt
 	     formatted field width.  */
 	  unsigned sf_read_comma : 1;
           /* A namelist specific flag used to enable reading input from 
-	       line_buffer for logical reads.  */
+	     line_buffer for logical reads.  */
 	  unsigned line_buffer_enabled : 1;
 	  /* 18 unused bits.  */
 
@@ -434,8 +434,9 @@ typedef struct st_parameter_dt
 	     enough to hold a complex value (two reals) of the largest
 	     kind.  */
 	  char value[32];
+	  gfc_offset size_used;
 	} p;
-      char pad[16 * sizeof (char *) + 34 * sizeof (int)];
+      char pad[16 * sizeof (char *) + 34 * sizeof (int) - sizeof (gfc_offset)];
     } u;
 }
 st_parameter_dt;
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index a72b4da2b570..6097c35d8a46 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -233,7 +233,7 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error)
   dtp->u.p.current_unit->bytes_left -= *length;
 
   if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
-    *dtp->size += *length;
+    dtp->u.p.size_used += (gfc_offset) *length;
 
   return base;
 }
@@ -277,7 +277,7 @@ read_block (st_parameter_dt *dtp, int *length)
   source = salloc_r (dtp->u.p.current_unit->s, &nread);
 
   if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
-    *dtp->size += nread;
+    dtp->u.p.size_used += (gfc_offset) nread;
 
   if (nread != *length)
     {				/* Short read, this shouldn't happen.  */
@@ -334,7 +334,7 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
     }
 
   if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
-    *dtp->size += (GFC_INTEGER_4) nread;
+    dtp->u.p.size_used += (gfc_offset) nread;
 
   if (nread != *nbytes)
     {				/* Short read, e.g. if we hit EOF.  */
@@ -375,7 +375,7 @@ write_block (st_parameter_dt *dtp, int length)
     }
 
   if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
-    *dtp->size += length;
+    dtp->u.p.size_used += (gfc_offset) length;
 
   return dest;
 }
@@ -404,10 +404,7 @@ write_buf (st_parameter_dt *dtp, void *buf, size_t nbytes)
     }
 
   if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
-    {
-      *dtp->size += (GFC_INTEGER_4) nbytes;
-      return FAILURE;
-    }
+    dtp->u.p.size_used += (gfc_offset) nbytes;
 
   return SUCCESS;
 }
@@ -1388,7 +1385,7 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
   dtp->u.p.mode = read_flag ? READING : WRITING;
 
   if ((cf & IOPARM_DT_HAS_SIZE) != 0)
-    *dtp->size = 0;		/* Initialize the count.  */
+    dtp->u.p.size_used = 0;  /* Initialize the count.  */
 
   dtp->u.p.current_unit = get_unit (dtp, 1);
   if (dtp->u.p.current_unit->s == NULL)
@@ -2147,6 +2144,9 @@ finalize_transfer (st_parameter_dt *dtp)
   jmp_buf eof_jump;
   GFC_INTEGER_4 cf = dtp->common.flags;
 
+  if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
+    *dtp->size = (GFC_INTEGER_4) dtp->u.p.size_used;
+
   if (dtp->u.p.eor_condition)
     {
       generate_error (&dtp->common, ERROR_EOR, NULL);
-- 
GitLab