[flang-commits] [flang] [flang][runtime] Handle end of internal output correctly (PR #84994)

via flang-commits flang-commits at lists.llvm.org
Tue Mar 12 16:30:24 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-runtime

Author: Peter Klausler (klausler)

<details>
<summary>Changes</summary>

At the end of an internal output statement, be sure to finish any following control edit descriptors in the format (if any), and (for output) advance to the next record.  Return the right I/O error status code if output overruns the buffer.

---
Full diff: https://github.com/llvm/llvm-project/pull/84994.diff


4 Files Affected:

- (modified) flang/runtime/internal-unit.cpp (+5-1) 
- (modified) flang/runtime/io-stmt.cpp (+12-4) 
- (modified) flang/runtime/io-stmt.h (+1) 
- (modified) flang/unittests/Runtime/NumericalFormatTest.cpp (+2-1) 


``````````diff
diff --git a/flang/runtime/internal-unit.cpp b/flang/runtime/internal-unit.cpp
index e3fffaa6f378ff..46d442a7cdd726 100644
--- a/flang/runtime/internal-unit.cpp
+++ b/flang/runtime/internal-unit.cpp
@@ -109,7 +109,11 @@ std::size_t InternalDescriptorUnit<DIR>::GetNextInputBytes(
 template <Direction DIR>
 bool InternalDescriptorUnit<DIR>::AdvanceRecord(IoErrorHandler &handler) {
   if (currentRecordNumber >= endfileRecordNumber.value_or(0)) {
-    handler.SignalEnd();
+    if constexpr (DIR == Direction::Input) {
+      handler.SignalEnd();
+    } else {
+      handler.SignalError(IostatInternalWriteOverrun);
+    }
     return false;
   }
   if constexpr (DIR == Direction::Output) {
diff --git a/flang/runtime/io-stmt.cpp b/flang/runtime/io-stmt.cpp
index 3ec01ffba9bf06..bdee947481bf98 100644
--- a/flang/runtime/io-stmt.cpp
+++ b/flang/runtime/io-stmt.cpp
@@ -118,6 +118,16 @@ template <Direction DIR> void InternalIoStatementState<DIR>::BackspaceRecord() {
   unit_.BackspaceRecord(*this);
 }
 
+template <Direction DIR>
+void InternalIoStatementState<DIR>::CompleteOperation() {
+  if (!this->completedOperation()) {
+    if constexpr (DIR == Direction::Output) {
+      unit_.AdvanceRecord(*this);
+    }
+    IoStatementBase::CompleteOperation();
+  }
+}
+
 template <Direction DIR> int InternalIoStatementState<DIR>::EndIoStatement() {
   if constexpr (DIR == Direction::Output) {
     unit_.EndIoStatement(); // fill
@@ -164,10 +174,8 @@ InternalFormattedIoStatementState<DIR, CHAR>::InternalFormattedIoStatementState(
 template <Direction DIR, typename CHAR>
 void InternalFormattedIoStatementState<DIR, CHAR>::CompleteOperation() {
   if (!this->completedOperation()) {
-    if constexpr (DIR == Direction::Output) {
-      format_.Finish(*this); // ignore any remaining input positioning actions
-    }
-    IoStatementBase::CompleteOperation();
+    format_.Finish(*this);
+    InternalIoStatementState<DIR>::CompleteOperation();
   }
 }
 
diff --git a/flang/runtime/io-stmt.h b/flang/runtime/io-stmt.h
index 0b6bcbd9af025a..2deef950d7f63e 100644
--- a/flang/runtime/io-stmt.h
+++ b/flang/runtime/io-stmt.h
@@ -346,6 +346,7 @@ class InternalIoStatementState : public IoStatementBase,
       const char *sourceFile = nullptr, int sourceLine = 0);
   InternalIoStatementState(
       const Descriptor &, const char *sourceFile = nullptr, int sourceLine = 0);
+  void CompleteOperation();
   int EndIoStatement();
 
   bool Emit(const char *data, std::size_t bytes, std::size_t elementBytes = 0);
diff --git a/flang/unittests/Runtime/NumericalFormatTest.cpp b/flang/unittests/Runtime/NumericalFormatTest.cpp
index 37eecd7708a1eb..ffde461fd82324 100644
--- a/flang/unittests/Runtime/NumericalFormatTest.cpp
+++ b/flang/unittests/Runtime/NumericalFormatTest.cpp
@@ -104,7 +104,7 @@ TEST(IOApiTests, HelloWorldOutputTest) {
 
 TEST(IOApiTests, MultilineOutputTest) {
   // Allocate buffer for multiline output
-  static constexpr int numLines{5};
+  static constexpr int numLines{6};
   static constexpr int lineLength{32};
   char buffer[numLines][lineLength];
 
@@ -159,6 +159,7 @@ TEST(IOApiTests, MultilineOutputTest) {
                                   "                                "
                                   "789                 abcd 666 777"
                                   " 888 999                        "
+                                  "                                "
                                   "................................"};
   // Ensure formatted string matches expected output
   EXPECT_TRUE(

``````````

</details>


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


More information about the flang-commits mailing list