https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128107
Bug ID: 128107
Summary: Advancing formatted STREAM read past short record
causes cumulative persistent POS error
Product: gcc
Version: 15.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libfortran
Assignee: unassigned at gcc dot gnu.org
Reporter: juno.krahn at gmail dot com
Target Milestone: ---
Created attachment 65936
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65936&action=edit
Short fortran code demonstrating the bug, writes file 'test.dat'
With ACCESS='STREAM', FORM='FORMATTED', an advancing formatted read whose input
list extends beyond the physical end of the current record leaves the
connection's POS incorrectly advanced. The error persists for subsequent I/O on
the unit for thr remainder of the file.
For a record containing 8 I6 values, the correct position following the record
is 50. Reading 8 or 9 integers reports POS=50, but requesting additional
integers causes a cumulative offset:
8/8 -> POS 50
9/8 -> POS 50
10/8 -> POS 51
11/8 -> POS 52
12/8 -> POS 53
Subsequent advancing reads remain displaced by the same amount. For example,
after the 12/8 case, records that should leave the stream at positions 55 and
60 instead report positions 58 and 63.
The physical file confirms that byte/file-storage-unit 49 is the newline
terminating the first record and position 50 is the first character of the
following record. Thus the additional positions do not correspond to storage
units actually consumed from the file.
The behavior is independent of PAD=. An explicit subsequent
READ(...,POS=<correct position>) positions the stream correctly, indicating
that POS= seeking itself works; the incorrect state is introduced by the
advancing formatted read past the short record.
A work-around implementation is to use advance='NO', then manually advance with
a dummy read based on iostat==IOSTAT_EOR.
Note:attached test code generates a dummy data file 'test.dat' and produces
this output, consistent across multiple gfortran versions up to 15.2.1. Note
that p3 is POS= state after the read and should be 60 in all cases.
STREAM read, advance='yes'
read 8/ 8, p1=50,p2=55,text="ABCD", p3=60,text="EFGH"
ABCD 55
read 9/ 8, p1=50,p2=55,text="ABCD", p3=60,text="EFGH"
ABCD 55
read 10/ 8, p1=51,p2=56,text="ABCD", p3=61,text="EFGH"
ABCD 55
read 11/ 8, p1=52,p2=57,text="ABCD", p3=62,text="EFGH"
ABCD 55
read 12/ 8, p1=53,p2=58,text="ABCD", p3=63,text="EFGH"
ABCD 55
work-around: STREAM read, advance='no', then manually advance if not EOR
read 8/ 8, p1=50,p2=55,text="ABCD", p3=60,text="EFGH"
read 9/ 8, p1=50,p2=55,text="ABCD", p3=60,text="EFGH"
read 10/ 8, p1=50,p2=55,text="ABCD", p3=60,text="EFGH"
read 11/ 8, p1=50,p2=55,text="ABCD", p3=60,text="EFGH"
read 12/ 8, p1=50,p2=55,text="ABCD", p3=60,text="EFGH"