[flang-commits] [flang] 1a65d09 - [flang][runtime] Keep frame buffer in sync with file when truncating

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Wed Jul 13 16:16:34 PDT 2022


Author: Peter Klausler
Date: 2022-07-13T16:12:12-07:00
New Revision: 1a65d09dcf9b9bed89f8c4fd848a056ebb507597

URL: https://github.com/llvm/llvm-project/commit/1a65d09dcf9b9bed89f8c4fd848a056ebb507597
DIFF: https://github.com/llvm/llvm-project/commit/1a65d09dcf9b9bed89f8c4fd848a056ebb507597.diff

LOG: [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

Added: 
    

Modified: 
    flang/runtime/buffer.h
    flang/runtime/unit.cpp

Removed: 
    


################################################################################
diff  --git a/flang/runtime/buffer.h b/flang/runtime/buffer.h
index 0bc3e0a37ded..a77a5a5dda5c 100644
--- a/flang/runtime/buffer.h
+++ b/flang/runtime/buffer.h
@@ -128,6 +128,15 @@ template <typename STORE, std::size_t minBuffer = 65536> class FileFrame {
     }
   }
 
+  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 a96b43d6a2c9..018c4332415d 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;
 }


        


More information about the flang-commits mailing list