[flang] Respect left tab limit with Tn editing after ADVANCE='NO'
authorPeter Klausler <pklausler@nvidia.com>
Thu, 31 Mar 2022 23:46:02 +0000 (16:46 -0700)
committerPeter Klausler <pklausler@nvidia.com>
Thu, 14 Apr 2022 04:45:53 +0000 (21:45 -0700)
Correct the implementation of non-advancing I/O after some testing
to ensure that T tab edit descriptors are not allowed to back up
into positions of a record prior to where it stood at the beginning
of the I/O statement.

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

flang/runtime/connection.h
flang/runtime/io-stmt.cpp
flang/runtime/io-stmt.h
flang/runtime/unit.cpp
flang/runtime/unit.h

index b36f7d1..c86b694 100644 (file)
@@ -47,7 +47,6 @@ struct ConnectionState : public ConnectionAttributes {
   void BeginRecord() {
     positionInRecord = 0;
     furthestPositionInRecord = 0;
-    leftTabLimit.reset();
   }
 
   std::optional<std::int64_t> EffectiveRecordLength() const {
index 3671f11..caa7d29 100644 (file)
@@ -199,17 +199,6 @@ MutableModes &ExternalIoStatementBase::mutableModes() { return unit_.modes; }
 
 ConnectionState &ExternalIoStatementBase::GetConnectionState() { return unit_; }
 
-void ExternalIoStatementBase::CompleteOperation() {
-  if (!completedOperation()) {
-    if (mutableModes().nonAdvancing) {
-      unit_.leftTabLimit = unit_.furthestPositionInRecord;
-    } else {
-      unit_.leftTabLimit.reset();
-    }
-    IoStatementBase::CompleteOperation();
-  }
-}
-
 int ExternalIoStatementBase::EndIoStatement() {
   CompleteOperation();
   auto result{IoStatementBase::EndIoStatement()};
@@ -330,12 +319,15 @@ void ExternalIoStatementState<DIR>::CompleteOperation() {
       FinishReadingRecord();
     }
   } else {
-    if (!mutableModes().nonAdvancing) {
+    if (mutableModes().nonAdvancing) {
+      unit().leftTabLimit = unit().furthestPositionInRecord;
+    } else {
+      unit().leftTabLimit.reset();
       unit().AdvanceRecord(*this);
     }
     unit().FlushIfTerminal(*this);
   }
-  return ExternalIoStatementBase::CompleteOperation();
+  return IoStatementBase::CompleteOperation();
 }
 
 template <Direction DIR> int ExternalIoStatementState<DIR>::EndIoStatement() {
@@ -1013,7 +1005,7 @@ void ExternalMiscIoStatementState::CompleteOperation() {
     ext.Rewind(*this);
     break;
   }
-  return ExternalIoStatementBase::CompleteOperation();
+  return IoStatementBase::CompleteOperation();
 }
 
 int ExternalMiscIoStatementState::EndIoStatement() {
index 0ed14e5..72d6bf6 100644 (file)
@@ -406,7 +406,6 @@ public:
   ExternalFileUnit &unit() { return unit_; }
   MutableModes &mutableModes();
   ConnectionState &GetConnectionState();
-  void CompleteOperation();
   int EndIoStatement();
   ExternalFileUnit *GetExternalFileUnit() const { return &unit_; }
 
index 2ba4faf..e9eae5b 100644 (file)
@@ -410,11 +410,6 @@ bool ExternalFileUnit::SetVariableFormattedRecordLength() {
   return false;
 }
 
-void ExternalFileUnit::SetLeftTabLimit() {
-  leftTabLimit = furthestPositionInRecord;
-  positionInRecord = furthestPositionInRecord;
-}
-
 bool ExternalFileUnit::BeginReadingRecord(IoErrorHandler &handler) {
   RUNTIME_CHECK(handler, direction_ == Direction::Input);
   if (!beganReadingRecord_) {
index 6e1a5ff..9b9d78c 100644 (file)
@@ -83,7 +83,6 @@ public:
       const char *, std::size_t, std::size_t elementBytes, IoErrorHandler &);
   bool Receive(char *, std::size_t, std::size_t elementBytes, IoErrorHandler &);
   std::size_t GetNextInputBytes(const char *&, IoErrorHandler &);
-  void SetLeftTabLimit();
   bool BeginReadingRecord(IoErrorHandler &);
   void FinishReadingRecord(IoErrorHandler &);
   bool AdvanceRecord(IoErrorHandler &);