[flang-commits] [flang] 142db43 - [flang][runtime] Allow recovery from BACKSPACE(badUnit)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Wed Jun 15 13:01:04 PDT 2022


Author: Peter Klausler
Date: 2022-06-15T13:00:54-07:00
New Revision: 142db43b626c0186302327598c7bef615efb564c

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

LOG: [flang][runtime] Allow recovery from BACKSPACE(badUnit)

When an unconnected unit number is used in a BACKSPACE statement
with ERR=, IOSTAT=, &/or IOMSG= control specifiers, don't crash,
but let the program deal with the error.

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

Added: 
    

Modified: 
    flang/include/flang/Runtime/iostat.h
    flang/runtime/io-api.cpp
    flang/runtime/io-stmt.cpp
    flang/runtime/io-stmt.h
    flang/runtime/iostat.cpp
    flang/runtime/unit.cpp
    flang/runtime/unit.h

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Runtime/iostat.h b/flang/include/flang/Runtime/iostat.h
index cfde0448fbf28..1ae6890678b4e 100644
--- a/flang/include/flang/Runtime/iostat.h
+++ b/flang/include/flang/Runtime/iostat.h
@@ -79,6 +79,7 @@ enum Iostat {
   IostatCannotReposition,
   IostatBadWaitId,
   IostatTooManyAsyncOps,
+  IostatBadBackspaceUnit,
 };
 
 const char *IostatErrorString(int);

diff  --git a/flang/runtime/io-api.cpp b/flang/runtime/io-api.cpp
index 42f4c2bcc7600..af79757c2add7 100644
--- a/flang/runtime/io-api.cpp
+++ b/flang/runtime/io-api.cpp
@@ -395,10 +395,17 @@ Cookie IONAME(BeginFlush)(
 Cookie IONAME(BeginBackspace)(
     ExternalUnit unitNumber, const char *sourceFile, int sourceLine) {
   Terminator terminator{sourceFile, sourceLine};
-  ExternalFileUnit &unit{
-      ExternalFileUnit::LookUpOrCrash(unitNumber, terminator)};
-  return &unit.BeginIoStatement<ExternalMiscIoStatementState>(
-      unit, ExternalMiscIoStatementState::Backspace, sourceFile, sourceLine);
+  if (ExternalFileUnit * unit{ExternalFileUnit::LookUp(unitNumber)}) {
+    return &unit->BeginIoStatement<ExternalMiscIoStatementState>(
+        *unit, ExternalMiscIoStatementState::Backspace, sourceFile, sourceLine);
+  } else {
+    auto &io{
+        New<NoopStatementState>{terminator}(sourceFile, sourceLine, unitNumber)
+            .release()
+            ->ioStatementState()};
+    io.GetIoErrorHandler().SetPendingError(IostatBadBackspaceUnit);
+    return &io;
+  }
 }
 
 Cookie IONAME(BeginEndfile)(

diff  --git a/flang/runtime/io-stmt.cpp b/flang/runtime/io-stmt.cpp
index 480cbea81821e..3bc3eba7a86b4 100644
--- a/flang/runtime/io-stmt.cpp
+++ b/flang/runtime/io-stmt.cpp
@@ -287,6 +287,7 @@ int CloseStatementState::EndIoStatement() {
 }
 
 void NoUnitIoStatementState::CompleteOperation() {
+  SignalPendingError();
   IoStatementBase::CompleteOperation();
 }
 

diff  --git a/flang/runtime/io-stmt.h b/flang/runtime/io-stmt.h
index 5e3209b7acab6..d343abe61140e 100644
--- a/flang/runtime/io-stmt.h
+++ b/flang/runtime/io-stmt.h
@@ -590,7 +590,8 @@ class CloseStatementState : public ExternalIoStatementBase {
   CloseStatus status_{CloseStatus::Keep};
 };
 
-// For CLOSE(bad unit), WAIT(bad unit, ID=nonzero) and INQUIRE(unconnected unit)
+// For CLOSE(bad unit), WAIT(bad unit, ID=nonzero), INQUIRE(unconnected unit),
+// and recoverable BACKSPACE(bad unit)
 class NoUnitIoStatementState : public IoStatementBase {
 public:
   IoStatementState &ioStatementState() { return ioStatementState_; }

diff  --git a/flang/runtime/iostat.cpp b/flang/runtime/iostat.cpp
index 3008c6e763d5a..a1df37a7647c2 100644
--- a/flang/runtime/iostat.cpp
+++ b/flang/runtime/iostat.cpp
@@ -103,6 +103,8 @@ const char *IostatErrorString(int iostat) {
     return "WAIT(ID=nonzero) for an ID value that is not a pending operation";
   case IostatTooManyAsyncOps:
     return "Too many asynchronous operations pending on unit";
+  case IostatBadBackspaceUnit:
+    return "BACKSPACE on unconnected unit";
   default:
     return nullptr;
   }

diff  --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp
index 27ad178d5b273..036ff9bfb2b5c 100644
--- a/flang/runtime/unit.cpp
+++ b/flang/runtime/unit.cpp
@@ -43,15 +43,6 @@ ExternalFileUnit *ExternalFileUnit::LookUp(int unit) {
   return GetUnitMap().LookUp(unit);
 }
 
-ExternalFileUnit &ExternalFileUnit::LookUpOrCrash(
-    int unit, const Terminator &terminator) {
-  ExternalFileUnit *file{LookUp(unit)};
-  if (!file) {
-    terminator.Crash("%d is not an open I/O unit number", unit);
-  }
-  return *file;
-}
-
 ExternalFileUnit &ExternalFileUnit::LookUpOrCreate(
     int unit, const Terminator &terminator, bool &wasExtant) {
   return GetUnitMap().LookUpOrCreate(unit, terminator, wasExtant);

diff  --git a/flang/runtime/unit.h b/flang/runtime/unit.h
index 3d024ba28800f..dca5e297b2544 100644
--- a/flang/runtime/unit.h
+++ b/flang/runtime/unit.h
@@ -47,7 +47,6 @@ class ExternalFileUnit : public ConnectionState,
   bool createdForInternalChildIo() const { return createdForInternalChildIo_; }
 
   static ExternalFileUnit *LookUp(int unit);
-  static ExternalFileUnit &LookUpOrCrash(int unit, const Terminator &);
   static ExternalFileUnit &LookUpOrCreate(
       int unit, const Terminator &, bool &wasExtant);
   static ExternalFileUnit &LookUpOrCreateAnonymous(int unit, Direction,


        


More information about the flang-commits mailing list