Skip to content

Commit

Permalink
[flang] runtime: fix WRITE after BACKSPACE on variable-length file
Browse files Browse the repository at this point in the history
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
  • Loading branch information
klausler committed Aug 24, 2021
1 parent 3265b93 commit b232a88
Showing 1 changed file with 14 additions and 7 deletions.
21 changes: 14 additions & 7 deletions flang/runtime/unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,13 +258,20 @@ bool ExternalFileUnit::Emit(const char *data, std::size_t bytes,
std::size_t elementBytes, IoErrorHandler &handler) {
auto furthestAfter{std::max(furthestPositionInRecord,
positionInRecord + static_cast<std::int64_t>(bytes))};
if (furthestAfter > recordLength.value_or(furthestAfter)) {
handler.SignalError(IostatRecordWriteOverrun,
"Attempt to write %zd bytes to position %jd in a fixed-size record of "
"%jd bytes",
bytes, static_cast<std::intmax_t>(positionInRecord),
static_cast<std::intmax_t>(*recordLength));
return false;
if (recordLength) {
// It is possible for recordLength to have a value now for a
// variable-length output record if the previous operation
// was a BACKSPACE.
if (!isFixedRecordLength) {
recordLength.reset();
} else if (furthestAfter > *recordLength) {
handler.SignalError(IostatRecordWriteOverrun,
"Attempt to write %zd bytes to position %jd in a fixed-size record "
"of %jd bytes",
bytes, static_cast<std::intmax_t>(positionInRecord),
static_cast<std::intmax_t>(*recordLength));
return false;
}
}
WriteFrame(frameOffsetInFile_, recordOffsetInFrame_ + furthestAfter, handler);
if (positionInRecord > furthestPositionInRecord) {
Expand Down

0 comments on commit b232a88

Please sign in to comment.