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

via flang-commits flang-commits at lists.llvm.org
Thu May 23 15:32:18 PDT 2024


Author: Peter Klausler
Date: 2024-05-23T15:32:14-07:00
New Revision: 975579bd94d4b130cf6363375d9e723281cb0ce5

URL: https://github.com/llvm/llvm-project/commit/975579bd94d4b130cf6363375d9e723281cb0ce5
DIFF: https://github.com/llvm/llvm-project/commit/975579bd94d4b130cf6363375d9e723281cb0ce5.diff

LOG: [flang] Fix variable unformatted I/O bug with output after input (#92828)

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.

Added: 
    

Modified: 
    flang/runtime/external-unit.cpp
    flang/runtime/unit.cpp

Removed: 
    


################################################################################
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();
 }


        


More information about the flang-commits mailing list