re PR libfortran/16908 (Segfault in libgfortran/io/transfer.c)
authorBud Davis <bdavis9659@comcast.net>
Sat, 21 Aug 2004 11:20:29 +0000 (11:20 +0000)
committerPaul Brook <pbrook@gcc.gnu.org>
Sat, 21 Aug 2004 11:20:29 +0000 (11:20 +0000)
2004-08-21  Bud Davis  <bdavis9659@comcast.net>

PR 16908
* io/transfer.c (next_record_w): Do not blank pad.
* io/transfer.c (next_record): Take into account partial records.
testsuite/
* gfortran.dg/direct_io.f90: New test.

From-SVN: r86361

gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/direct_io_1.f90 [new file with mode: 0644]
libgfortran/ChangeLog
libgfortran/io/transfer.c

index 24756293f5f725a76fba838ed00276e478513fe4..de614afc6de76bc13e4231d2f666ae8eb6833940 100644 (file)
@@ -1,3 +1,8 @@
+2004-08-21  Bud Davis  <bdavis9659@comcast.net>
+
+       PR 16908
+       * gfortran.dg/direct_io.f90: New test.
+
 2004-08-20  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/17121
diff --git a/gcc/testsuite/gfortran.dg/direct_io_1.f90 b/gcc/testsuite/gfortran.dg/direct_io_1.f90
new file mode 100644 (file)
index 0000000..db79c6e
--- /dev/null
@@ -0,0 +1,31 @@
+! PR 16908
+! Segfaulted on second set of writes.  We weren't handling partial records
+! properly when calculating the file position.
+program direct_io_1
+  implicit none
+
+  integer n, nt, mt, m
+  real dt, tm, w
+  real, allocatable :: p(:)
+
+  nt =  2049 ! if nt < 2049, then everything works.
+
+  allocate(p(nt))
+  p  = 0.e0
+
+  inquire(iolength=mt) (p(m), m=1, nt)
+
+  open(unit=12, file='syn.sax', access='direct', recl=mt)
+  n = 1
+  write(12, rec=n) mt, nt
+  write(12, rec=n+1) (p(m), m=1, nt)
+  close(12)
+
+  inquire(iolength=mt) (p(m), m=1, nt)
+
+  open(unit=12, file='syn.sax', access='direct', recl=mt)
+  n = 1
+  write(12, rec=n) mt, nt
+  write(12, rec=n+1) (p(m), m=1, nt)
+  close(12)
+end program
index ff4e9456aacc9f067393012b48d304af0ee7f307..46d5061492af678c4400eed63fdb2cec0b20001a 100644 (file)
@@ -1,3 +1,9 @@
+2004-08-21  Bud Davis  <bdavis9659@comcast.net>
+
+       PR 16908
+       * io/transfer.c (next_record_w): Do not blank pad.
+       * io/transfer.c (next_record): Take into account partial records.
+
 2004-08-18  Victor Leikehman  <lei@il.ibm.com>
 
        PR fortran/13278
index d4bec91ea31e90e6050de6145fec6b7835d1187f..5bc3c002b6086b775a800139b701986d8558e9ad 100644 (file)
@@ -1223,20 +1223,23 @@ next_record_w (int done)
   switch (current_mode ())
     {
     case FORMATTED_DIRECT:
-    case UNFORMATTED_DIRECT:
       if (current_unit->bytes_left == 0)
        break;
 
       length = current_unit->bytes_left;
-
       p = salloc_w (current_unit->s, &length);
+
       if (p == NULL)
        goto io_error;
 
       memset (p, ' ', current_unit->bytes_left);
       if (sfree (current_unit->s) == FAILURE)
        goto io_error;
+      break;
 
+    case UNFORMATTED_DIRECT:
+      if (sfree (current_unit->s) == FAILURE)
+        goto io_error;
       break;
 
     case UNFORMATTED_SEQUENTIAL:
@@ -1304,6 +1307,7 @@ next_record_w (int done)
 void
 next_record (int done)
 {
+  gfc_offset fp; /* file position */
 
   current_unit->read_bad = 0;
 
@@ -1314,8 +1318,12 @@ next_record (int done)
 
   current_unit->current_record = 0;
   if (current_unit->flags.access == ACCESS_DIRECT)
-    current_unit->last_record = file_position (current_unit->s) 
-                               / current_unit->recl;
+   {
+    fp = file_position (current_unit->s);
+    /* Calculate next record, rounding up partial records.  */
+    current_unit->last_record = (fp + curren_unit->recl - 1)
+                               / current_unit->recl;
+   }
   else
     current_unit->last_record++;