aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Klausler <pklausler@nvidia.com>2022-07-07 14:51:40 -0700
committerPeter Klausler <pklausler@nvidia.com>2022-07-13 16:12:12 -0700
commit1a65d09dcf9b9bed89f8c4fd848a056ebb507597 (patch)
tree14e28cafc2b5949ce52aac5603c283e2bf6ef6f0
parentfaffcc3a46cb667fb8e2e6d0e6c14ed74300d7b5 (diff)
downloadllvm-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.h9
-rw-r--r--flang/runtime/unit.cpp4
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;
}