[flang-commits] [flang] eac925f - [flang][runtime] Better handling of "fort.N" opening errors (#96347)

via flang-commits flang-commits at lists.llvm.org
Mon Jun 24 10:34:42 PDT 2024


Author: Peter Klausler
Date: 2024-06-24T10:34:37-07:00
New Revision: eac925fb81f26342811ad1765e8f9919628e2254

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

LOG: [flang][runtime] Better handling of "fort.N" opening errors (#96347)

When a data transfer statement references a unit number that hasn't been
explicitly OPENed, the runtime I/O support library opens a local
"fort.N" file where N is the unit number. If that name exists in the
current working directory but is not a readable or writable file (as
appropriate), the runtime needs to catch the error at the point of the
READ or WRITE statement rather than leaving an open unit in the unit map
without a valid file descriptor.

Added: 
    

Modified: 
    flang/runtime/external-unit.cpp
    flang/runtime/pseudo-unit.cpp
    flang/runtime/unit.h

Removed: 
    


################################################################################
diff  --git a/flang/runtime/external-unit.cpp b/flang/runtime/external-unit.cpp
index 328c994a180b1..8009151a8a370 100644
--- a/flang/runtime/external-unit.cpp
+++ b/flang/runtime/external-unit.cpp
@@ -65,10 +65,17 @@ ExternalFileUnit *ExternalFileUnit::LookUpOrCreateAnonymous(int unit,
   bool exists{false};
   ExternalFileUnit *result{GetUnitMap().LookUpOrCreate(unit, handler, exists)};
   if (result && !exists) {
-    result->OpenAnonymousUnit(
-        dir == Direction::Input ? OpenStatus::Unknown : OpenStatus::Replace,
-        Action::ReadWrite, Position::Rewind, Convert::Unknown, handler);
-    result->isUnformatted = isUnformatted;
+    if (!result->OpenAnonymousUnit(
+            dir == Direction::Input ? OpenStatus::Unknown : OpenStatus::Replace,
+            Action::ReadWrite, Position::Rewind, Convert::Unknown, handler)) {
+      // fort.N isn't a writable file
+      if (ExternalFileUnit * closed{LookUpForClose(result->unitNumber())}) {
+        closed->DestroyClosed();
+      }
+      result = nullptr;
+    } else {
+      result->isUnformatted = isUnformatted;
+    }
   }
   return result;
 }
@@ -183,7 +190,7 @@ bool ExternalFileUnit::OpenUnit(Fortran::common::optional<OpenStatus> status,
   return impliedClose;
 }
 
-void ExternalFileUnit::OpenAnonymousUnit(
+bool ExternalFileUnit::OpenAnonymousUnit(
     Fortran::common::optional<OpenStatus> status,
     Fortran::common::optional<Action> action, Position position,
     Convert convert, IoErrorHandler &handler) {
@@ -193,6 +200,7 @@ void ExternalFileUnit::OpenAnonymousUnit(
   std::snprintf(path.get(), pathMaxLen, "fort.%d", unitNumber_);
   OpenUnit(status, action, position, std::move(path), std::strlen(path.get()),
       convert, handler);
+  return IsConnected();
 }
 
 void ExternalFileUnit::CloseUnit(CloseStatus status, IoErrorHandler &handler) {

diff  --git a/flang/runtime/pseudo-unit.cpp b/flang/runtime/pseudo-unit.cpp
index 70e70eec6a77e..526afd11d916e 100644
--- a/flang/runtime/pseudo-unit.cpp
+++ b/flang/runtime/pseudo-unit.cpp
@@ -65,7 +65,7 @@ bool ExternalFileUnit::OpenUnit(Fortran::common::optional<OpenStatus> status,
   handler.Crash("%s: unsupported", RT_PRETTY_FUNCTION);
 }
 
-void ExternalFileUnit::OpenAnonymousUnit(Fortran::common::optional<OpenStatus>,
+bool ExternalFileUnit::OpenAnonymousUnit(Fortran::common::optional<OpenStatus>,
     Fortran::common::optional<Action>, Position, Convert convert,
     IoErrorHandler &handler) {
   handler.Crash("%s: unsupported", RT_PRETTY_FUNCTION);

diff  --git a/flang/runtime/unit.h b/flang/runtime/unit.h
index abd535fd0381d..83f839e205a48 100644
--- a/flang/runtime/unit.h
+++ b/flang/runtime/unit.h
@@ -134,7 +134,7 @@ class ExternalFileUnit : public ConnectionState,
   RT_API_ATTRS bool OpenUnit(Fortran::common::optional<OpenStatus>,
       Fortran::common::optional<Action>, Position, OwningPtr<char> &&path,
       std::size_t pathLength, Convert, IoErrorHandler &);
-  RT_API_ATTRS void OpenAnonymousUnit(Fortran::common::optional<OpenStatus>,
+  RT_API_ATTRS bool OpenAnonymousUnit(Fortran::common::optional<OpenStatus>,
       Fortran::common::optional<Action>, Position, Convert, IoErrorHandler &);
   RT_API_ATTRS void CloseUnit(CloseStatus, IoErrorHandler &);
   RT_API_ATTRS void DestroyClosed();


        


More information about the flang-commits mailing list