From 9c5f89006fa4b64c77997f660554a12315f4ac1d Mon Sep 17 00:00:00 2001 From: Jerry DeLisle Date: Mon, 14 Jan 2019 00:22:00 +0000 Subject: [PATCH] re PR libfortran/88776 (Namelist read from stdin: loss of data) 2019-01-13 Jerry DeLisle PR libfortran/88776 * io/open.c (newunit): Free format buffer if the unit specified is for stdin, stdout, or stderr. * gfortran.dg/namelist_96.f90: New test. From-SVN: r267910 --- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gfortran.dg/namelist_96.f90 | 38 +++++++++++++++++++++++ libgfortran/ChangeLog | 6 ++++ libgfortran/io/open.c | 16 +++++++--- 4 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/namelist_96.f90 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 33a7f95464d..d0611e3bc37 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-01-13 Jerry DeLisle + + PR libfortran/88776 + * gfortran.dg/namelist_96.f90: New test. + 2019-01-13 Thomas Koenig PR fortran/59345 diff --git a/gcc/testsuite/gfortran.dg/namelist_96.f90 b/gcc/testsuite/gfortran.dg/namelist_96.f90 new file mode 100644 index 00000000000..5606e1f7754 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/namelist_96.f90 @@ -0,0 +1,38 @@ +! ( dg-do run } +program pr88776 + implicit none + character(*), parameter :: file = "pr88776.dat" + type t_chan + integer :: ichan = -1 + character(len=8) :: flag = '' + integer :: band = -1 + end type t_chan + type(t_chan) :: chan + namelist /NML/ chan + open (11,file=file) + write(11,'(a)') trim("&nml chan = 1 '#1 ' 10 /") + write(11,'(a)') trim("&nml chan = 2 '#2 ' 42.36/") + write(11,'(a)') trim("&nml chan = 3 '#3 ' 30 /") + close(11) + call read (unit=10) ! No problem + call read (unit=5) ! problem, now fixed + open (11,file=file) + close (11, status="delete") +contains + subroutine read (unit) + integer, intent(in) :: unit + integer :: stat + open (unit, file=file, action="read") + chan = t_chan(-1,'',-1) + stat = 0 + read (unit, nml=NML, iostat=stat) + if (stat /= 0) stop 1 + chan = t_chan(-1,'',-1) + read (unit, nml=NML, iostat=stat) + if (stat == 0) stop 2 + if (chan% ichan /= 2) then + stop 3 + end if + close (unit) + end subroutine read +end program pr88776 diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index f63e3782734..274160d4b9e 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,9 @@ +2019-01-13 Jerry DeLisle + + PR libfortran/88776 + * io/open.c (newunit): Free format buffer if the unit specified is for + stdin, stdout, or stderr. + 2019-01-12 Jerry DeLisle PR libfortran/88776 diff --git a/libgfortran/io/open.c b/libgfortran/io/open.c index 97fb17c7424..b48afabf7a3 100644 --- a/libgfortran/io/open.c +++ b/libgfortran/io/open.c @@ -530,6 +530,14 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags *flags) if (u2 != NULL) unlock_unit (u2); + /* If the unit specified is preconnected with a file specified to be open, + then clear the format buffer. */ + if ((opp->common.unit == options.stdin_unit || + opp->common.unit == options.stdout_unit || + opp->common.unit == options.stderr_unit) + && (opp->common.flags & IOPARM_OPEN_HAS_FILE) != 0) + fbuf_destroy (u); + /* Open file. */ s = open_external (opp, flags); @@ -705,12 +713,12 @@ already_open (st_parameter_open *opp, gfc_unit *u, unit_flags *flags) if (u->filename && u->flags.status == STATUS_SCRATCH) remove (u->filename); #endif - free (u->filename); - u->filename = NULL; - + free (u->filename); + u->filename = NULL; + u = new_unit (opp, u, flags); if (u != NULL) - unlock_unit (u); + unlock_unit (u); return; } -- 2.30.2