[flang-commits] [flang] cea8b8a - [flang][runtime] Don't pad CHARACTER input at end of record unless PAD='YES'

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Mon May 9 12:47:44 PDT 2022


Author: Peter Klausler
Date: 2022-05-09T12:39:43-07:00
New Revision: cea8b8a72d877a796c1e97fca2adae8a85bb36a1

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

LOG: [flang][runtime] Don't pad CHARACTER input at end of record unless PAD='YES'

When formatted CHARACTER input runs into the end of an input record,
the runtime usually fills the remainder of the variable with spaces,
but this should be conditional, and not done when PAD='NO'.

And while here, add some better comments to two members of connection.h
to make their non-obvious relationship more clear.

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

Added: 
    

Modified: 
    flang/runtime/connection.h
    flang/runtime/edit-input.cpp
    flang/runtime/io-api.cpp
    flang/unittests/Runtime/ExternalIOTest.cpp

Removed: 
    


################################################################################
diff  --git a/flang/runtime/connection.h b/flang/runtime/connection.h
index a19c49f9aa048..ba880b22c975e 100644
--- a/flang/runtime/connection.h
+++ b/flang/runtime/connection.h
@@ -66,9 +66,17 @@ struct ConnectionState : public ConnectionAttributes {
 
   std::optional<std::int64_t> recordLength;
 
-  // Positions in a record file (sequential or direct, not stream)
   std::int64_t currentRecordNumber{1}; // 1 is first
-  std::int64_t positionInRecord{0}; // offset in current record
+
+  // positionInRecord is the 0-based offset in the current recurd to/from
+  // which the next data transfer will occur.  It can be past
+  // furthestPositionInRecord if moved by an X or T or TR control edit
+  // descriptor.
+  std::int64_t positionInRecord{0};
+
+  // furthestPositionInRecord is the 0-based offset of the greatest
+  // position in the current record to/from which any data transfer has
+  // occurred, plus one.  It can be viewed as a count of bytes processed.
   std::int64_t furthestPositionInRecord{0}; // max(position+bytes)
 
   // Set at end of non-advancing I/O data transfer

diff  --git a/flang/runtime/edit-input.cpp b/flang/runtime/edit-input.cpp
index b694749ccc226..2e8ea3faa9e3e 100644
--- a/flang/runtime/edit-input.cpp
+++ b/flang/runtime/edit-input.cpp
@@ -679,11 +679,10 @@ bool EditCharacterInput(
     remaining = *edit.width;
   }
   // When the field is wider than the variable, we drop the leading
-  // characters.  When the variable is wider than the field, there's
+  // characters.  When the variable is wider than the field, there can be
   // trailing padding.
   const char *input{nullptr};
   std::size_t ready{0};
-  bool hitEnd{false};
   // Skip leading bytes.
   // These bytes don't count towards INQUIRE(IOLENGTH=).
   std::size_t skip{remaining > length ? remaining - length : 0};
@@ -692,8 +691,10 @@ bool EditCharacterInput(
     if (ready == 0) {
       ready = io.GetNextInputBytes(input);
       if (ready == 0) {
-        hitEnd = true;
-        break;
+        if (io.CheckForEndOfRecord()) {
+          std::fill_n(x, length, ' '); // PAD='YES'
+        }
+        return !io.GetIoErrorHandler().InError();
       }
     }
     std::size_t chunk;
@@ -731,9 +732,6 @@ bool EditCharacterInput(
   }
   // Pad the remainder of the input variable, if any.
   std::fill_n(x, length, ' ');
-  if (hitEnd) {
-    io.CheckForEndOfRecord(); // signal any needed error
-  }
   return true;
 }
 

diff  --git a/flang/runtime/io-api.cpp b/flang/runtime/io-api.cpp
index 43e49daa1284b..d5ef844ec557c 100644
--- a/flang/runtime/io-api.cpp
+++ b/flang/runtime/io-api.cpp
@@ -1176,7 +1176,7 @@ bool IONAME(InputCharacter)(
 }
 
 bool IONAME(InputAscii)(Cookie cookie, char *x, std::size_t length) {
-  return IONAME(InputCharacter(cookie, x, length, 1));
+  return IONAME(InputCharacter)(cookie, x, length, 1);
 }
 
 bool IONAME(OutputLogical)(Cookie cookie, bool truth) {

diff  --git a/flang/unittests/Runtime/ExternalIOTest.cpp b/flang/unittests/Runtime/ExternalIOTest.cpp
index 87b1ef91addd1..a129204908315 100644
--- a/flang/unittests/Runtime/ExternalIOTest.cpp
+++ b/flang/unittests/Runtime/ExternalIOTest.cpp
@@ -544,8 +544,9 @@ TEST(ExternalIOTests, TestNonAvancingInput) {
         fmt.data(), fmt.length(), unit, __FILE__, __LINE__);
     IONAME(EnableHandlers)(io, true, false, false, false, false);
     ASSERT_TRUE(IONAME(SetAdvance)(io, "NO", 2)) << "SetAdvance(NO)" << j;
-    ASSERT_TRUE(
-        IONAME(InputAscii)(io, inputItem.item.data(), inputItem.item.length()))
+    bool result{
+        IONAME(InputAscii)(io, inputItem.item.data(), inputItem.item.length())};
+    ASSERT_EQ(result, inputItem.expectedIoStat == IostatOk)
         << "InputAscii() " << j;
     ASSERT_EQ(IONAME(EndIoStatement)(io), inputItem.expectedIoStat)
         << "EndIoStatement() for Read " << j;


        


More information about the flang-commits mailing list