[flang-commits] [flang] 0f5c60f - [flang] Fix edge-case I/O regressions

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Tue Feb 1 16:27:56 PST 2022


Author: Peter Klausler
Date: 2022-02-01T16:27:47-08:00
New Revision: 0f5c60f151e1991a7880cfc5311f7b1c61ce1528

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

LOG: [flang] Fix edge-case I/O regressions

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.

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

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/flang/runtime/edit-input.cpp b/flang/runtime/edit-input.cpp
index dff79841cf18c..3460661cc4270 100644
--- a/flang/runtime/edit-input.cpp
+++ b/flang/runtime/edit-input.cpp
@@ -99,8 +99,8 @@ bool EditIntegerInput(
   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 @@ bool EditIntegerInput(
     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 @@ static int ScanRealInput(char *buffer, int bufferSize, IoStatementState &io,
   }
   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 @@ static bool EditListDirectedDefaultCharacterInput(
     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 @@ bool EditDefaultCharacterInput(
         edit.descriptor);
     return false;
   }
+  if (io.GetConnectionState().IsAtEOF()) {
+    return false;
+  }
   std::optional<int> remaining{length};
   if (edit.width && *edit.width > 0) {
     remaining = *edit.width;

diff  --git a/flang/runtime/internal-unit.cpp b/flang/runtime/internal-unit.cpp
index 7842cfb2e4494..0c833ba548ec7 100644
--- a/flang/runtime/internal-unit.cpp
+++ b/flang/runtime/internal-unit.cpp
@@ -39,7 +39,9 @@ InternalDescriptorUnit<DIR>::InternalDescriptorUnit(
 
 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();
     }
   }


        


More information about the flang-commits mailing list