[flang-commits] [flang] [llvm] [flang-rt] Split large unformatted sequential records into subrecords (PR #213003)

via flang-commits flang-commits at lists.llvm.org
Fri Oct 16 03:18:31 PDT 2026


================
@@ -710,40 +877,37 @@ void ExternalFileUnit::BackspaceFixedRecord(IoErrorHandler &handler) {
 
 void ExternalFileUnit::BackspaceVariableUnformattedRecord(
     IoErrorHandler &handler) {
-  std::uint32_t header{0};
-  auto headerBytes{static_cast<std::int64_t>(sizeof header)};
   frameOffsetInFile_ += recordOffsetInFrame_;
   recordOffsetInFrame_ = 0;
-  if (frameOffsetInFile_ <= headerBytes) {
+  if (frameOffsetInFile_ <= static_cast<FileOffset>(kRecMarkSize)) {
     handler.SignalError(IostatBackspaceAtFirstRecord);
     return;
   }
-  // Error conditions here cause crashes, not file format errors, because the
-  // validity of the file structure before the current record will have been
-  // checked informatively in NextSequentialVariableUnformattedInputRecord().
-  std::size_t got{
-      ReadFrame(frameOffsetInFile_ - headerBytes, headerBytes, handler)};
-  if (static_cast<std::int64_t>(got) < headerBytes) {
-    handler.SignalError(IostatShortRead);
-    return;
-  }
-  recordLength = ReadHeaderOrFooter(0);
-  if (frameOffsetInFile_ < *recordLength + 2 * headerBytes) {
-    handler.SignalError(IostatBadUnformattedRecord);
-    return;
-  }
-  frameOffsetInFile_ -= *recordLength + 2 * headerBytes;
-  auto need{static_cast<std::size_t>(
-      recordOffsetInFrame_ + sizeof header + *recordLength)};
-  got = ReadFrame(frameOffsetInFile_, need, handler);
-  if (got < need) {
+  std::int32_t marker{0};
+  do {
+    if (ReadFrame(frameOffsetInFile_ - kRecMarkSize, kRecMarkSize, handler) <
+        kRecMarkSize) {
+      handler.SignalError(IostatShortRead);
+      return;
+    }
+    marker = LoadRecordMarker(Frame(), swapEndianness_);
+    auto payload{SubrecordPayloadBytes(marker)};
+    if (frameOffsetInFile_ <
+        static_cast<FileOffset>(payload + 2 * kRecMarkSize)) {
+      handler.SignalError(IostatBadUnformattedRecord);
+      return;
+    }
+    frameOffsetInFile_ -= static_cast<FileOffset>(payload + 2 * kRecMarkSize);
+  } while (marker < 0);
+  auto need{
+      static_cast<std::size_t>(kRecMarkSize + SubrecordPayloadBytes(marker))};
+  if (ReadFrame(frameOffsetInFile_, need, handler) < need) {
----------------
ejose02 wrote:

Done.Now read only the 4-byte header for validation, not 4 + payload.

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


More information about the flang-commits mailing list