This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[Patch, libgfortran] PR26464 Runtime I/O error/invald argument on READ


:ADDPATCH fortran:

With additional test cases and time I was able to track this bug down to handling the after endfile conditions in backspace. I will confess a lot of trial and error, testing, and hunches went into finding this.

The patch reverts the addition of flush to st_read_done which I did for pr25835. It adds a flush and truncate to backspace when AFTER_ENDFILE. Two test cases are added. These bugs involve interaction with buffering as well and the errors could be present or go away depending on array sizes because pre_position was not getting oriented correctly to read the record markers.

Thanks to Dale Ranta for the test cases.

NIST tested, regression tested, Mega-IO tested (aka Dale's automatic combo tests)

OK for trunk? and 4.1.1 after freeze?

Best Regards,

Jerry

2006-02-26 Jerry DeLisle <jvdelisle@gcc.gnu.org>

	PR libgfortran/26464
	* io/file_pos.c (st_backspace): Flush and truncate file
	when in AFTER_ENDFILE condition.
	(st_read_done): Remove flush, no longer needed.

Index: io/file_pos.c
===================================================================
*** io/file_pos.c	(revision 111437)
--- io/file_pos.c	(working copy)
*************** st_backspace (st_parameter_filepos *fpp)
*** 161,167 ****
    /* Check for special cases involving the ENDFILE record first.  */
  
    if (u->endfile == AFTER_ENDFILE)
!     u->endfile = AT_ENDFILE;
    else
      {
        if (file_position (u->s) == 0)
--- 161,171 ----
    /* Check for special cases involving the ENDFILE record first.  */
  
    if (u->endfile == AFTER_ENDFILE)
!     {
!       u->endfile = AT_ENDFILE;
!       flush (u->s);
!       struncate (u->s);
!     }
    else
      {
        if (file_position (u->s) == 0)
Index: io/transfer.c
===================================================================
*** io/transfer.c	(revision 111437)
--- io/transfer.c	(working copy)
*************** export_proto(st_read_done);
*** 2159,2165 ****
  void
  st_read_done (st_parameter_dt *dtp)
  {
-   flush(dtp->u.p.current_unit->s);
    finalize_transfer (dtp);
    free_format_data (dtp);
    free_ionml (dtp);
--- 2159,2164 ----
!{ dg-do run }
! PR26464 File I/O error related to buffering and BACKSPACE
! Test case derived from case by Dale Ranta.
! Submitted  by Jerry DeLisle  <jvdelisle@gcc.gnu.org>
      program test
      integer,parameter :: datasize = 1000
      dimension idata(datasize)
      open (11, status="scratch", form="unformatted")
        idata(1)   =  -1
        idata(  datasize)   =  -2
       write(11)idata
        idata(1)   =  -2
        idata(  datasize)   =  -3
       write(11)idata
        idata(1)   =  -3
        idata(  datasize)   =  -4
       write(11)idata
        idata(1)   =  -4
        idata(  datasize)   =  -5
       write(11)idata
       read(11,end=        1000 )idata
       call abort()
 1000  continue
       backspace 11
       backspace 11
       backspace 11
       read(11,end=        1001 )idata
        if(idata(1).ne.  -3.or.idata(  datasize).ne.  -4)then
            write(6,*)idata(1),idata(  datasize)
            call abort()
        endif
        stop
 1001  continue
       call abort()
 1010  stop
       end
       
!{ dg-do run }
! PR26464 File I/O error related to buffering and BACKSPACE
! Test case derived from case by Dale Ranta.
! Submitted  by Jerry DeLisle  <jvdelisle@gcc.gnu.org>
      program test
      integer,parameter :: datasize = 5000
      dimension idata(datasize)
      open (11, status="scratch", form="unformatted")
        idata(1)   =  -1
        idata(datasize)   =  -2
       write(11)idata
        idata(1)   =  -2
        idata(datasize)   =  -3
       write(11)idata
        idata(1)   =  -3
        idata(datasize)   =  -4
       write(11)idata
       backspace 11
       backspace 11
        idata(1)   =  -2
        idata(datasize)   =  -3
       write(11)idata
       read(11,end=        1003 )idata
       call abort()
 1003  continue
       backspace 11
       backspace 11
       read(11,end=        1004 )idata
        if(idata(1).ne.-2 .or.idata(datasize).ne.-3) call abort()
       stop	
 1004  continue
       end
       

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