[flang-commits] [flang] [flang] Fix variable unformatted I/O bug with output after input (PR #92828)

via flang-commits flang-commits at lists.llvm.org
Mon May 20 15:18:18 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-runtime

Author: Peter Klausler (klausler)

<details>
<summary>Changes</summary>

When reading variable-length unformatted records, the external I/O library frames the input buffer so that the footer of the previous record remains in frame.  This is done so that a BACKSPACE doesn't have to do an extra read to get the length of the previous record before repositioning over it.

When switching from input to output to overwrite or append new records after reading any, it is necessary to undo this framing of the last word in the previous record, since the new output isn't going to define it in the buffer and it'll be overwritten in the filesystem with garbage.

---
Full diff: https://github.com/llvm/llvm-project/pull/92828.diff


2 Files Affected:

- (modified) flang/runtime/external-unit.cpp (+7-1) 
- (modified) flang/runtime/unit.cpp (+1) 


``````````diff
diff --git a/flang/runtime/external-unit.cpp b/flang/runtime/external-unit.cpp
index b48549d54587e..4bfa218bb7769 100644
--- a/flang/runtime/external-unit.cpp
+++ b/flang/runtime/external-unit.cpp
@@ -214,6 +214,13 @@ Iostat ExternalFileUnit::SetDirection(Direction direction) {
     }
   } else {
     if (mayWrite()) {
+      if (direction_ == Direction::Input) {
+        // Don't retain any input data from previous record, like a
+        // variable-length unformatted record footer, in the frame,
+        // since we're going start writing frames.
+        frameOffsetInFile_ += recordOffsetInFrame_;
+        recordOffsetInFrame_ = 0;
+      }
       direction_ = Direction::Output;
       return IostatOk;
     } else {
@@ -332,5 +339,4 @@ bool ExternalFileUnit::Wait(int id) {
 }
 
 } // namespace Fortran::runtime::io
-
 #endif // !defined(RT_USE_PSEUDO_FILE_UNIT)
diff --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp
index 3b42f45d55884..a11f444d8d754 100644
--- a/flang/runtime/unit.cpp
+++ b/flang/runtime/unit.cpp
@@ -265,6 +265,7 @@ void ExternalFileUnit::FinishReadingRecord(IoErrorHandler &handler) {
     furthestPositionInRecord =
         std::max(furthestPositionInRecord, positionInRecord);
     frameOffsetInFile_ += recordOffsetInFrame_ + furthestPositionInRecord;
+    recordOffsetInFrame_ = 0;
   }
   BeginRecord();
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/92828


More information about the flang-commits mailing list