[flang-commits] [PATCH] D112243: [flang] Emit unformatted headers & footers even with RECL=

Peter Klausler via Phabricator via flang-commits flang-commits at lists.llvm.org
Thu Oct 21 10:49:46 PDT 2021


klausler created this revision.
klausler added a reviewer: vdonaldson.
klausler added a project: Flang.
Herald added a subscriber: jdoerfert.
klausler requested review of this revision.

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.


https://reviews.llvm.org/D112243

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


Index: flang/runtime/unit.cpp
===================================================================
--- flang/runtime/unit.cpp
+++ flang/runtime/unit.cpp
@@ -375,7 +375,7 @@
     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 @@
     // 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 @@
   } 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 @@
         // 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 @@
       DoImpliedEndfile(handler);
       if (frameOffsetInFile_ + recordOffsetInFrame_ > 0) {
         --currentRecordNumber;
-        if (isFixedRecordLength) {
+        if (isFixedRecordLength && access == Access::Direct) {
           BackspaceFixedRecord(handler);
         } else {
           RUNTIME_CHECK(handler, isUnformatted.has_value());
Index: flang/runtime/io-api.cpp
===================================================================
--- flang/runtime/io-api.cpp
+++ flang/runtime/io-api.cpp
@@ -268,9 +268,9 @@
     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
       }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D112243.381323.patch
Type: text/x-patch
Size: 3802 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20211021/522a546b/attachment-0001.bin>


More information about the flang-commits mailing list