From: Bud Davis Date: Fri, 27 Aug 2004 07:59:30 +0000 (+0000) Subject: re PR libfortran/16597 (gfortran: bug in unformatted I/O on scratch files) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=55948b693ed0cde602e64e7f670450a0e5e96b93;p=gcc.git re PR libfortran/16597 (gfortran: bug in unformatted I/O on scratch files) 2004-08-27 Bud Davis PR fortran/16597 * io/io.h: created typedef for unit_mode. * io/io.h (gfc_unit): added mode to unit structure. * io/transfer.c (data_transfer_init): flush if a write then read is done on a unit (direct access files). * io/rewind.c (st_rewind): Used unit mode instead of global. * gfortran.dg/pr16597.f90: New test. From-SVN: r86654 --- diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9b73b6dea53..18f803758a6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-08-27 Bud Davis + + PR fortran/16597 + * gfortran.dg/pr16597.f90: New test. + 2004-08-26 Joseph S. Myers PR c/13801 diff --git a/gcc/testsuite/gfortran.dg/pr16597.f90 b/gcc/testsuite/gfortran.dg/pr16597.f90 new file mode 100644 index 00000000000..ff1dcb838ae --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr16597.f90 @@ -0,0 +1,27 @@ +! pr 16597 +! libgfortran +! reading a direct access record after it was written did +! not always return the correct data. + + program gfbug4 + implicit none + + integer strlen + parameter (strlen = 4) + + integer iunit + character string *4 + + iunit = 99 + open (UNIT=iunit,FORM='unformatted',ACCESS='direct',RECL=strlen) + write (iunit, rec=1) 'ABCD' + read (iunit, rec=1) string + close (iunit) + if (string.ne.'ABCD') call abort + + open (UNIT=iunit,FORM='unformatted',ACCESS='direct',STATUS='scratch',RECL=strlen) + write (iunit, rec=1) 'ABCD' + read (iunit, rec=1) string + close (iunit) + if (string.ne.'ABCD') call abort + end diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 33e16c9dd31..e0039ec0ac9 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,12 @@ +2004-08-27 Bud Davis + + PR fortran/16597 + * io/io.h: created typedef for unit_mode. + * io/io.h (gfc_unit): added mode to unit structure. + * io/transfer.c (data_transfer_init): flush if a write then + read is done on a unit (direct access files). + * io/rewind.c (st_rewind): Used unit mode instead of global. + 2004-08-24 Bud Davis PR fortran/17143 diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h index 796a6247f21..d2c15af7ec7 100644 --- a/libgfortran/io/io.h +++ b/libgfortran/io/io.h @@ -144,7 +144,9 @@ typedef enum { ADVANCE_YES, ADVANCE_NO, ADVANCE_UNSPECIFIED } unit_advance; - +typedef enum +{READING, WRITING} +unit_mode; /* Statement parameters. These are all the things that can appear in an I/O statement. Some are inputs and some are outputs, but none @@ -271,6 +273,7 @@ typedef struct gfc_unit { NO_ENDFILE, AT_ENDFILE, AFTER_ENDFILE } endfile; + unit_mode mode; unit_flags flags; gfc_offset recl, last_record, maxrec, bytes_left; @@ -299,7 +302,7 @@ typedef struct gfc_unit *unit_root; int seen_dollar; - enum {READING, WRITING} mode; + unit_mode mode; unit_blank blank_status; enum {SIGN_S, SIGN_SS, SIGN_SP} sign_status; diff --git a/libgfortran/io/rewind.c b/libgfortran/io/rewind.c index 76fd1948e05..d9758a6d5ec 100644 --- a/libgfortran/io/rewind.c +++ b/libgfortran/io/rewind.c @@ -40,7 +40,7 @@ st_rewind (void) "Cannot REWIND a file opened for DIRECT access"); else { - if (g.mode==WRITING) + if (u->mode==WRITING) struncate(u->s); u->last_record = 0; if (sseek (u->s, 0) == FAILURE) diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index b6f7c0e0129..3800d0b90cb 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -1044,13 +1044,19 @@ data_transfer_init (int read_flag) return; } - /* Position the file. */ + /* Check to see if we might be reading what we wrote before */ + + if (g.mode == READING && current_unit->mode == WRITING) + flush(current_unit->s); + /* Position the file. */ if (sseek (current_unit->s, (ioparm.rec - 1) * current_unit->recl) == FAILURE) generate_error (ERROR_OS, NULL); } + current_unit->mode = g.mode; + /* Set the initial value of flags. */ g.blank_status = current_unit->flags.blank;