[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