This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Fwd: [PATCH, libgfortran] Fix PR26890 SIZE parameter interacts with variable in IO list]


:ADDPATCH fortran: Forgot the patch tracker.

-------- Original Message --------
Subject: [PATCH, libgfortran] Fix PR26890 SIZE parameter interacts with variable in IO list
Date: Wed, 29 Mar 2006 21:37:11 -0800
From: Jerry DeLisle <jvdelisle@verizon.net>
To: Fortran List <fortran@gcc.gnu.org>, gcc-patches <gcc-patches@gcc.gnu.org>


Hello Folks,

The attached patch fixes this bug by adding a new variable to the dtp structure
in io.h.  The pad variable size is adjusted by the sizeof (gfc_offset) to
compensate for this (to keep the structure size identical).  I have not
identified any other use for this padding that is there. (Please comment if you
know anything about it)

The new variable, size_used, is used to accumulate the bytes read or written.
The SIZE parameter is then set to the accumulated value when the transfer is
complete.

Regression tested, NIST tested, io tested. See attached test case.

OK for trunk? What about 4.1.1?

Regards Jerry

2006-03-29 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.

Index: io/io.h
===================================================================
*** io/io.h	(revision 112399)
--- io/io.h	(working copy)
*************** typedef struct st_parameter_dt
*** 434,441 ****
  	     enough to hold a complex value (two reals) of the largest
  	     kind.  */
  	  char value[32];
  	} p;
!       char pad[16 * sizeof (char *) + 34 * sizeof (int)];
      } u;
  }
  st_parameter_dt;
--- 434,442 ----
  	     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) - sizeof (gfc_offset)];
      } u;
  }
  st_parameter_dt;
Index: io/transfer.c
===================================================================
*** io/transfer.c	(revision 112399)
--- io/transfer.c	(working copy)
*************** read_sf (st_parameter_dt *dtp, int *leng
*** 233,239 ****
    dtp->u.p.current_unit->bytes_left -= *length;
  
    if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
!     *dtp->size += *length;
  
    return base;
  }
--- 233,239 ----
    dtp->u.p.current_unit->bytes_left -= *length;
  
    if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
!     dtp->u.p.size_used += (gfc_offset) *length;
  
    return base;
  }
*************** read_block (st_parameter_dt *dtp, int *l
*** 277,283 ****
    source = salloc_r (dtp->u.p.current_unit->s, &nread);
  
    if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
!     *dtp->size += nread;
  
    if (nread != *length)
      {				/* Short read, this shouldn't happen.  */
--- 277,283 ----
    source = salloc_r (dtp->u.p.current_unit->s, &nread);
  
    if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
!     dtp->u.p.size_used += (gfc_offset) nread;
  
    if (nread != *length)
      {				/* Short read, this shouldn't happen.  */
*************** read_block_direct (st_parameter_dt *dtp,
*** 334,340 ****
      }
  
    if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
!     *dtp->size += (GFC_INTEGER_4) nread;
  
    if (nread != *nbytes)
      {				/* Short read, e.g. if we hit EOF.  */
--- 334,340 ----
      }
  
    if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
!     dtp->u.p.size_used += (gfc_offset) nread;
  
    if (nread != *nbytes)
      {				/* Short read, e.g. if we hit EOF.  */
*************** write_block (st_parameter_dt *dtp, int l
*** 375,381 ****
      }
  
    if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
!     *dtp->size += length;
  
    return dest;
  }
--- 375,381 ----
      }
  
    if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
!     dtp->u.p.size_used += (gfc_offset) length;
  
    return dest;
  }
*************** write_buf (st_parameter_dt *dtp, void *b
*** 404,413 ****
      }
  
    if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
!     {
!       *dtp->size += (GFC_INTEGER_4) nbytes;
!       return FAILURE;
!     }
  
    return SUCCESS;
  }
--- 404,410 ----
      }
  
    if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
!     dtp->u.p.size_used += (gfc_offset) nbytes;
  
    return SUCCESS;
  }
*************** data_transfer_init (st_parameter_dt *dtp
*** 1388,1394 ****
    dtp->u.p.mode = read_flag ? READING : WRITING;
  
    if ((cf & IOPARM_DT_HAS_SIZE) != 0)
!     *dtp->size = 0;		/* Initialize the count.  */
  
    dtp->u.p.current_unit = get_unit (dtp, 1);
    if (dtp->u.p.current_unit->s == NULL)
--- 1385,1391 ----
    dtp->u.p.mode = read_flag ? READING : WRITING;
  
    if ((cf & IOPARM_DT_HAS_SIZE) != 0)
!     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)
*************** finalize_transfer (st_parameter_dt *dtp)
*** 2147,2152 ****
--- 2144,2152 ----
    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);

Attachment: read_size_noadvance.f90
Description: application/extension-f90


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]