re PR libfortran/88776 (Namelist read from stdin: loss of data)
authorJerry DeLisle <jvdelisle@gcc.gnu.org>
Mon, 14 Jan 2019 00:22:00 +0000 (00:22 +0000)
committerJerry DeLisle <jvdelisle@gcc.gnu.org>
Mon, 14 Jan 2019 00:22:00 +0000 (00:22 +0000)
2019-01-13  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

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
gcc/testsuite/gfortran.dg/namelist_96.f90 [new file with mode: 0644]
libgfortran/ChangeLog
libgfortran/io/open.c

index 33a7f95..d0611e3 100644 (file)
@@ -1,3 +1,8 @@
+2019-01-13  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
+
+       PR libfortran/88776
+       * gfortran.dg/namelist_96.f90: New test.
+
 2019-01-13  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        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 (file)
index 0000000..5606e1f
--- /dev/null
@@ -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
index f63e378..274160d 100644 (file)
@@ -1,3 +1,9 @@
+2019-01-13  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
+
+       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  <jvdelisle@gcc.gnu.org>
 
        PR libfortran/88776
index 97fb17c..b48afab 100644 (file)
@@ -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;
     }