[flang-commits] [PATCH] D118720: [flang] Fix edge-case I/O regressions

Peter Klausler via Phabricator via flang-commits flang-commits at lists.llvm.org
Tue Feb 1 11:57:45 PST 2022


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.

A blank field in an input record that exists must be interpreted
as a zero value for numeric input editing, but advancing to a
next record that doesn't exist should leave an input variable
unmodified (and signal END=).  On internal output, blank fill
the "current record" array element even if nothing has been
written to it if it is the only record.


https://reviews.llvm.org/D118720

Files:
  flang/runtime/edit-input.cpp
  flang/runtime/internal-unit.cpp


Index: flang/runtime/internal-unit.cpp
===================================================================
--- flang/runtime/internal-unit.cpp
+++ flang/runtime/internal-unit.cpp
@@ -39,7 +39,9 @@
 
 template <Direction DIR> void InternalDescriptorUnit<DIR>::EndIoStatement() {
   if constexpr (DIR == Direction::Output) {
-    if (furthestPositionInRecord > 0) {
+    // Clear the remainder of the current record if anything was written
+    // to it, or if it is the only record.
+    if (endfileRecordNumber.value_or(-1) == 2 || furthestPositionInRecord > 0) {
       BlankFillOutputRecord();
     }
   }
Index: flang/runtime/edit-input.cpp
===================================================================
--- flang/runtime/edit-input.cpp
+++ flang/runtime/edit-input.cpp
@@ -99,8 +99,8 @@
   std::optional<int> remaining;
   std::optional<char32_t> next;
   bool negate{ScanNumericPrefix(io, edit, next, remaining)};
-  common::UnsignedInt128 value;
-  bool any{false};
+  common::UnsignedInt128 value{0};
+  bool any{negate};
   for (; next; next = io.NextInField(remaining)) {
     char32_t ch{*next};
     if (ch == ' ' || ch == '\t') {
@@ -122,11 +122,11 @@
     value += digit;
     any = true;
   }
-  if (any) {
-    if (negate) {
-      value = -value;
-    }
-    std::memcpy(n, &value, kind);
+  if (negate) {
+    value = -value;
+  }
+  if (any || !io.GetConnectionState().IsAtEOF()) {
+    std::memcpy(n, &value, kind); // a blank field means zero
   }
   return any;
 }
@@ -155,7 +155,9 @@
   }
   if (next.value_or(' ') == ' ') { // empty/blank field means zero
     remaining.reset();
-    Put('0');
+    if (!io.GetConnectionState().IsAtEOF()) {
+      Put('0');
+    }
     return got;
   }
   char32_t decimal{GetDecimalPoint(edit)};
@@ -524,7 +526,7 @@
     io.HandleRelativePosition(1);
     return EditDelimitedCharacterInput(io, x, length, *ch);
   }
-  if (IsNamelistName(io)) {
+  if (IsNamelistName(io) || io.GetConnectionState().IsAtEOF()) {
     return false;
   }
   // Undelimited list-directed character input: stop at a value separator
@@ -563,6 +565,9 @@
         edit.descriptor);
     return false;
   }
+  if (io.GetConnectionState().IsAtEOF()) {
+    return false;
+  }
   std::optional<int> remaining{length};
   if (edit.width && *edit.width > 0) {
     remaining = *edit.width;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D118720.405026.patch
Type: text/x-patch
Size: 2325 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20220201/31e6ae44/attachment.bin>


More information about the flang-commits mailing list