diff options
author | Peter Klausler <pklausler@nvidia.com> | 2022-07-07 14:51:40 -0700 |
---|---|---|
committer | Peter Klausler <pklausler@nvidia.com> | 2022-07-13 16:12:12 -0700 |
commit | 1a65d09dcf9b9bed89f8c4fd848a056ebb507597 (patch) | |
tree | 14e28cafc2b5949ce52aac5603c283e2bf6ef6f0 | |
parent | faffcc3a46cb667fb8e2e6d0e6c14ed74300d7b5 (diff) | |
download | llvm-1a65d09dcf9b9bed89f8c4fd848a056ebb507597.zip llvm-1a65d09dcf9b9bed89f8c4fd848a056ebb507597.tar.gz llvm-1a65d09dcf9b9bed89f8c4fd848a056ebb507597.tar.bz2 |
[flang][runtime] Keep frame buffer in sync with file when truncating
When the I/O runtime is truncating an external file due to an
implied ENDFILE or explicit ENDFILE, ensure that the unit's frame
buffer for the file discards any data that have become obsolete.
This bug caused trouble with ACCESS='STREAM' I/O using POS= on
a WRITE, but it may have not been limited to that scenario.
Differential Revision: https://reviews.llvm.org/D129673
-rw-r--r-- | flang/runtime/buffer.h | 9 | ||||
-rw-r--r-- | flang/runtime/unit.cpp | 4 |
2 files changed, 11 insertions, 2 deletions
diff --git a/flang/runtime/buffer.h b/flang/runtime/buffer.h index 0bc3e0a..a77a5a5 100644 --- a/flang/runtime/buffer.h +++ b/flang/runtime/buffer.h @@ -128,6 +128,15 @@ public: } } + void TruncateFrame(std::int64_t at, IoErrorHandler &handler) { + RUNTIME_CHECK(handler, !dirty_); + if (at <= fileOffset_) { + Reset(at); + } else if (at < fileOffset_ + length_) { + length_ = at - fileOffset_; + } + } + private: STORE &Store() { return static_cast<STORE &>(*this); } diff --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp index a96b43d..018c433 100644 --- a/flang/runtime/unit.cpp +++ b/flang/runtime/unit.cpp @@ -898,9 +898,9 @@ void ExternalFileUnit::DoEndfile(IoErrorHandler &handler) { } frameOffsetInFile_ += recordOffsetInFrame_ + furthestPositionInRecord; recordOffsetInFrame_ = 0; - // Flush (if dirty) and reset the frame (even if reading) - WriteFrame(frameOffsetInFile_, 0, handler); + FlushOutput(handler); Truncate(frameOffsetInFile_, handler); + TruncateFrame(frameOffsetInFile_, handler); BeginRecord(); impliedEndfile_ = false; } |