[flang-commits] [flang] ccc573c - [flang][runtime] When OPEN implies CLOSE, disable later extant unit c… (#69390)

via flang-commits flang-commits at lists.llvm.org
Tue Oct 31 10:25:33 PDT 2023


Author: Peter Klausler
Date: 2023-10-31T10:25:29-07:00
New Revision: ccc573c6d821b010217d0621fd271c0a7972ccba

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

LOG: [flang][runtime] When OPEN implies CLOSE, disable later extant unit c… (#69390)

…hecks

An OPEN statement on an existing unit can imply a CLOSE of that unit;
for example, OPEN(5, FILE="mydata", FORM="formatted") should implicitly
close the standard input that had been preconnected to unit 5. When this
happens, later checks in OPEN statement completion that apply only to
existing units should be disabled.

Added: 
    

Modified: 
    flang/runtime/io-stmt.cpp
    flang/runtime/unit.cpp
    flang/runtime/unit.h

Removed: 
    


################################################################################
diff  --git a/flang/runtime/io-stmt.cpp b/flang/runtime/io-stmt.cpp
index 1d951a4157d3199..dedf1f8364ad373 100644
--- a/flang/runtime/io-stmt.cpp
+++ b/flang/runtime/io-stmt.cpp
@@ -248,8 +248,10 @@ void OpenStatementState::CompleteOperation() {
   }
   if (path_.get() || wasExtant_ ||
       (status_ && *status_ == OpenStatus::Scratch)) {
-    unit().OpenUnit(status_, action_, position_.value_or(Position::AsIs),
-        std::move(path_), pathLength_, convert_, *this);
+    if (unit().OpenUnit(status_, action_, position_.value_or(Position::AsIs),
+            std::move(path_), pathLength_, convert_, *this)) {
+      wasExtant_ = false; // existing unit was closed
+    }
   } else {
     unit().OpenAnonymousUnit(
         status_, action_, position_.value_or(Position::AsIs), convert_, *this);

diff  --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp
index 1c8432328848e0f..dec8d8032f6155e 100644
--- a/flang/runtime/unit.cpp
+++ b/flang/runtime/unit.cpp
@@ -90,7 +90,7 @@ ExternalFileUnit &ExternalFileUnit::NewUnit(
   return unit;
 }
 
-void ExternalFileUnit::OpenUnit(std::optional<OpenStatus> status,
+bool ExternalFileUnit::OpenUnit(std::optional<OpenStatus> status,
     std::optional<Action> action, Position position, OwningPtr<char> &&newPath,
     std::size_t newPathLength, Convert convert, IoErrorHandler &handler) {
   if (convert == Convert::Unknown) {
@@ -99,24 +99,26 @@ void ExternalFileUnit::OpenUnit(std::optional<OpenStatus> status,
   swapEndianness_ = convert == Convert::Swap ||
       (convert == Convert::LittleEndian && !isHostLittleEndian) ||
       (convert == Convert::BigEndian && isHostLittleEndian);
+  bool impliedClose{false};
   if (IsConnected()) {
     bool isSamePath{newPath.get() && path() && pathLength() == newPathLength &&
         std::memcmp(path(), newPath.get(), newPathLength) == 0};
     if (status && *status != OpenStatus::Old && isSamePath) {
       handler.SignalError("OPEN statement for connected unit may not have "
                           "explicit STATUS= other than 'OLD'");
-      return;
+      return impliedClose;
     }
     if (!newPath.get() || isSamePath) {
       // OPEN of existing unit, STATUS='OLD' or unspecified, not new FILE=
       newPath.reset();
-      return;
+      return impliedClose;
     }
     // Otherwise, OPEN on open unit with new FILE= implies CLOSE
     DoImpliedEndfile(handler);
     FlushOutput(handler);
     TruncateFrame(0, handler);
     Close(CloseStatus::Keep, handler);
+    impliedClose = true;
   }
   if (newPath.get() && newPathLength > 0) {
     if (const auto *already{
@@ -125,7 +127,7 @@ void ExternalFileUnit::OpenUnit(std::optional<OpenStatus> status,
           "OPEN(UNIT=%d,FILE='%.*s'): file is already connected to unit %d",
           unitNumber_, static_cast<int>(newPathLength), newPath.get(),
           already->unitNumber_);
-      return;
+      return impliedClose;
     }
   }
   set_path(std::move(newPath), newPathLength);
@@ -166,6 +168,7 @@ void ExternalFileUnit::OpenUnit(std::optional<OpenStatus> status,
       currentRecordNumber = *endfileRecordNumber;
     }
   }
+  return impliedClose;
 }
 
 void ExternalFileUnit::OpenAnonymousUnit(std::optional<OpenStatus> status,

diff  --git a/flang/runtime/unit.h b/flang/runtime/unit.h
index b6007a9b1538595..1ec3013ba82b3fb 100644
--- a/flang/runtime/unit.h
+++ b/flang/runtime/unit.h
@@ -59,7 +59,8 @@ class ExternalFileUnit : public ConnectionState,
   static void CloseAll(IoErrorHandler &);
   static void FlushAll(IoErrorHandler &);
 
-  void OpenUnit(std::optional<OpenStatus>, std::optional<Action>, Position,
+  // Returns true if an existing unit was closed
+  bool OpenUnit(std::optional<OpenStatus>, std::optional<Action>, Position,
       OwningPtr<char> &&path, std::size_t pathLength, Convert,
       IoErrorHandler &);
   void OpenAnonymousUnit(std::optional<OpenStatus>, std::optional<Action>,


        


More information about the flang-commits mailing list