]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR libfortran/32752 (Segfault on WRITE with modified unix_stream structure)
authorJerry DeLisle <jvdelisle@gcc.gnu.org>
Sun, 22 Jul 2007 04:02:57 +0000 (04:02 +0000)
committerJerry DeLisle <jvdelisle@gcc.gnu.org>
Sun, 22 Jul 2007 04:02:57 +0000 (04:02 +0000)
2007-07-21  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

PR libgfortran/32752
PR libgfortran/32678
Backport from trunk.
* io/transfer.c (formatted_transfer_scalar): If stream I/O, set
bytes_used to zero. Fix off by one error in calculation of pos and
skips. Don't allow pending_spaces to go negative.

From-SVN: r126822

libgfortran/ChangeLog
libgfortran/io/transfer.c

index 1859509170d286a61180ecceb742a6789f8ac339..19ec2d6238bb062da979803372b8c62f4236d8a9 100644 (file)
@@ -1,3 +1,12 @@
+2007-07-21  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
+
+       PR libgfortran/32752
+       PR libgfortran/32678
+       Backport from trunk.
+       * io/transfer.c (formatted_transfer_scalar): If stream I/O, set
+       bytes_used to zero. Fix off by one error in calculation of pos and
+       skips. Don't allow pending_spaces to go negative.
+
 2007-07-19  Release Manager
 
        * GCC 4.2.1 released.
index d1cd01c774575bed8437ec256e71ddd9e42bb38d..0576297310882691a9e6248c685f2b950b926f9a 100644 (file)
@@ -957,7 +957,10 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int len,
        }
 
       bytes_used = (int)(dtp->u.p.current_unit->recl
-                        - dtp->u.p.current_unit->bytes_left);
+                  - dtp->u.p.current_unit->bytes_left);
+
+      if (is_stream_io(dtp))
+       bytes_used = 0;
 
       switch (t)
        {
@@ -1154,9 +1157,9 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int len,
        case FMT_TR:
          consume_data_flag = 0;
 
-         pos = bytes_used + f->u.n + dtp->u.p.skips;
-         dtp->u.p.skips = f->u.n + dtp->u.p.skips;
-         dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos;
+         dtp->u.p.skips += f->u.n;
+         pos = bytes_used + dtp->u.p.skips - 1;
+         dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1;
 
          /* Writes occur just before the switch on f->format, above, so
             that trailing blanks are suppressed, unless we are doing a
@@ -1186,8 +1189,6 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int len,
              if (bytes_used == 0)
                {
                  dtp->u.p.pending_spaces -= f->u.n;
-                 dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0 ? 0
-                                           : dtp->u.p.pending_spaces;
                  dtp->u.p.skips -= f->u.n;
                  dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips;
                }
@@ -1211,6 +1212,8 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int len,
          dtp->u.p.skips = dtp->u.p.skips + pos - bytes_used;
          dtp->u.p.pending_spaces = dtp->u.p.pending_spaces
                                    + pos - dtp->u.p.max_pos;
+         dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
+                                   ? 0 : dtp->u.p.pending_spaces;
 
          if (dtp->u.p.skips == 0)
            break;