[flang-commits] [flang] b03628d - [flang] Emit unformatted headers & footers even with RECL=

peter klausler via flang-commits flang-commits at lists.llvm.org
Fri Oct 22 11:07:08 PDT 2021


Author: peter klausler
Date: 2021-10-22T11:07:01-07:00
New Revision: b03628d986d47e41187278acd2e2b66dd3dc03ae

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

LOG: [flang] Emit unformatted headers & footers even with RECL=

The runtime library was emitting unformatted record headers and
footers when an external unit had no fixed RECL=.  This is wrong
for sequential files, which should have headers & footers even
with RECL.  Change to omit headers & footers from unformatted
I/O only for direct access files.

Differential Revision: https://reviews.llvm.org/D112243

Added: 
    

Modified: 
    flang/runtime/io-api.cpp
    flang/runtime/unit.cpp

Removed: 
    


################################################################################
diff  --git a/flang/runtime/io-api.cpp b/flang/runtime/io-api.cpp
index 061f1552270f..977e192e6c83 100644
--- a/flang/runtime/io-api.cpp
+++ b/flang/runtime/io-api.cpp
@@ -268,9 +268,9 @@ Cookie BeginUnformattedIO(
     IoErrorHandler handler{terminator};
     unit.SetDirection(DIR, handler);
     if constexpr (DIR == Direction::Output) {
-      if (unit.access == Access::Sequential && !unit.isFixedRecordLength) {
+      if (unit.access == Access::Sequential) {
         // Create space for (sub)record header to be completed by
-        // ExternalUnformattedIoStatementState<Direction::Output>::EndIoStatement()
+        // ExternalFileUnit::AdvanceRecord()
         unit.recordLength.reset(); // in case of prior BACKSPACE
         io.Emit("\0\0\0\0", 4); // placeholder for record length header
       }

diff  --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp
index baeb54efaaa6..6c146e66e32c 100644
--- a/flang/runtime/unit.cpp
+++ b/flang/runtime/unit.cpp
@@ -375,7 +375,7 @@ bool ExternalFileUnit::BeginReadingRecord(IoErrorHandler &handler) {
     if (access == Access::Sequential) {
       if (endfileRecordNumber && currentRecordNumber >= *endfileRecordNumber) {
         handler.SignalEnd();
-      } else if (isFixedRecordLength) {
+      } else if (isFixedRecordLength && access == Access::Direct) {
         RUNTIME_CHECK(handler, recordLength.has_value());
         auto need{
             static_cast<std::size_t>(recordOffsetInFrame_ + *recordLength)};
@@ -406,7 +406,7 @@ void ExternalFileUnit::FinishReadingRecord(IoErrorHandler &handler) {
     // avoid bogus crashes in END/ERR circumstances
   } else if (access == Access::Sequential) {
     RUNTIME_CHECK(handler, recordLength.has_value());
-    if (isFixedRecordLength) {
+    if (isFixedRecordLength && access == Access::Direct) {
       frameOffsetInFile_ += recordOffsetInFrame_ + *recordLength;
       recordOffsetInFrame_ = 0;
     } else {
@@ -444,17 +444,17 @@ bool ExternalFileUnit::AdvanceRecord(IoErrorHandler &handler) {
   } else { // Direction::Output
     bool ok{true};
     RUNTIME_CHECK(handler, isUnformatted.has_value());
-    if (isFixedRecordLength && recordLength) {
+    if (isFixedRecordLength && recordLength &&
+        furthestPositionInRecord < *recordLength) {
       // Pad remainder of fixed length record
-      if (furthestPositionInRecord < *recordLength) {
-        WriteFrame(
-            frameOffsetInFile_, recordOffsetInFrame_ + *recordLength, handler);
-        std::memset(Frame() + recordOffsetInFrame_ + furthestPositionInRecord,
-            isUnformatted.value_or(false) ? 0 : ' ',
-            *recordLength - furthestPositionInRecord);
-      }
-    } else {
-      positionInRecord = furthestPositionInRecord;
+      WriteFrame(
+          frameOffsetInFile_, recordOffsetInFrame_ + *recordLength, handler);
+      std::memset(Frame() + recordOffsetInFrame_ + furthestPositionInRecord,
+          isUnformatted.value_or(false) ? 0 : ' ',
+          *recordLength - furthestPositionInRecord);
+      furthestPositionInRecord = *recordLength;
+    }
+    if (!(isFixedRecordLength && access == Access::Direct)) {
       if (isUnformatted.value_or(false)) {
         // Append the length of a sequential unformatted variable-length record
         // as its footer, then overwrite the reserved first four bytes of the
@@ -464,6 +464,7 @@ bool ExternalFileUnit::AdvanceRecord(IoErrorHandler &handler) {
         // headers &/or footers
         std::uint32_t length;
         length = furthestPositionInRecord - sizeof length;
+        positionInRecord = furthestPositionInRecord;
         ok = ok &&
             Emit(reinterpret_cast<const char *>(&length), sizeof length,
                 sizeof length, handler);
@@ -498,7 +499,7 @@ void ExternalFileUnit::BackspaceRecord(IoErrorHandler &handler) {
       DoImpliedEndfile(handler);
       if (frameOffsetInFile_ + recordOffsetInFrame_ > 0) {
         --currentRecordNumber;
-        if (isFixedRecordLength) {
+        if (isFixedRecordLength && access == Access::Direct) {
           BackspaceFixedRecord(handler);
         } else {
           RUNTIME_CHECK(handler, isUnformatted.has_value());


        


More information about the flang-commits mailing list