Skip to content

Commit a4814f7

Browse files
klauslerjeanPerier
authored andcommitted
[flang] runtime: fix WRITE after BACKSPACE on variable-length file
BACKSPACE leaves "recordLength" set, which is fine for a later READ, but it causes a later WRITE to fail due to a misinterpretation of the knowledge of the record length as indication of a fixed-length record file (RECL=). Fix. Differential Revision: https://reviews.llvm.org/D108594
1 parent d3a2c6f commit a4814f7

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

flang/runtime/unit.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -258,13 +258,20 @@ bool ExternalFileUnit::Emit(const char *data, std::size_t bytes,
258258
std::size_t elementBytes, IoErrorHandler &handler) {
259259
auto furthestAfter{std::max(furthestPositionInRecord,
260260
positionInRecord + static_cast<std::int64_t>(bytes))};
261-
if (furthestAfter > recordLength.value_or(furthestAfter)) {
262-
handler.SignalError(IostatRecordWriteOverrun,
263-
"Attempt to write %zd bytes to position %jd in a fixed-size record of "
264-
"%jd bytes",
265-
bytes, static_cast<std::intmax_t>(positionInRecord),
266-
static_cast<std::intmax_t>(*recordLength));
267-
return false;
261+
if (recordLength) {
262+
// It is possible for recordLength to have a value now for a
263+
// variable-length output record if the previous operation
264+
// was a BACKSPACE.
265+
if (!isFixedRecordLength) {
266+
recordLength.reset();
267+
} else if (furthestAfter > *recordLength) {
268+
handler.SignalError(IostatRecordWriteOverrun,
269+
"Attempt to write %zd bytes to position %jd in a fixed-size record "
270+
"of %jd bytes",
271+
bytes, static_cast<std::intmax_t>(positionInRecord),
272+
static_cast<std::intmax_t>(*recordLength));
273+
return false;
274+
}
268275
}
269276
WriteFrame(frameOffsetInFile_, recordOffsetInFrame_ + furthestAfter, handler);
270277
if (positionInRecord > furthestPositionInRecord) {

0 commit comments

Comments
 (0)