Skip to content

Commit 975579b

Browse files
authored
[flang] Fix variable unformatted I/O bug with output after input (#92828)
When reading variable-length unformatted records, the external I/O library frames the input buffer so that the footer of the previous record remains in frame. This is done so that a BACKSPACE doesn't have to do an extra read to get the length of the previous record before repositioning over it. When switching from input to output to overwrite or append new records after reading any, it is necessary to undo this framing of the last word in the previous record, since the new output isn't going to define it in the buffer and it'll be overwritten in the filesystem with garbage.
1 parent 6d2b23c commit 975579b

File tree

2 files changed

+8
-1
lines changed

2 files changed

+8
-1
lines changed

flang/runtime/external-unit.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,13 @@ Iostat ExternalFileUnit::SetDirection(Direction direction) {
214214
}
215215
} else {
216216
if (mayWrite()) {
217+
if (direction_ == Direction::Input) {
218+
// Don't retain any input data from previous record, like a
219+
// variable-length unformatted record footer, in the frame,
220+
// since we're going start writing frames.
221+
frameOffsetInFile_ += recordOffsetInFrame_;
222+
recordOffsetInFrame_ = 0;
223+
}
217224
direction_ = Direction::Output;
218225
return IostatOk;
219226
} else {
@@ -332,5 +339,4 @@ bool ExternalFileUnit::Wait(int id) {
332339
}
333340

334341
} // namespace Fortran::runtime::io
335-
336342
#endif // !defined(RT_USE_PSEUDO_FILE_UNIT)

flang/runtime/unit.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ void ExternalFileUnit::FinishReadingRecord(IoErrorHandler &handler) {
265265
furthestPositionInRecord =
266266
std::max(furthestPositionInRecord, positionInRecord);
267267
frameOffsetInFile_ += recordOffsetInFrame_ + furthestPositionInRecord;
268+
recordOffsetInFrame_ = 0;
268269
}
269270
BeginRecord();
270271
}

0 commit comments

Comments
 (0)