Skip to content

Commit 142db43

Browse files
committed
[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
1 parent 2d82c9c commit 142db43

File tree

7 files changed

+17
-15
lines changed

7 files changed

+17
-15
lines changed

flang/include/flang/Runtime/iostat.h

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ enum Iostat {
7979
IostatCannotReposition,
8080
IostatBadWaitId,
8181
IostatTooManyAsyncOps,
82+
IostatBadBackspaceUnit,
8283
};
8384

8485
const char *IostatErrorString(int);

flang/runtime/io-api.cpp

+11-4
Original file line numberDiff line numberDiff line change
@@ -395,10 +395,17 @@ Cookie IONAME(BeginFlush)(
395395
Cookie IONAME(BeginBackspace)(
396396
ExternalUnit unitNumber, const char *sourceFile, int sourceLine) {
397397
Terminator terminator{sourceFile, sourceLine};
398-
ExternalFileUnit &unit{
399-
ExternalFileUnit::LookUpOrCrash(unitNumber, terminator)};
400-
return &unit.BeginIoStatement<ExternalMiscIoStatementState>(
401-
unit, ExternalMiscIoStatementState::Backspace, sourceFile, sourceLine);
398+
if (ExternalFileUnit * unit{ExternalFileUnit::LookUp(unitNumber)}) {
399+
return &unit->BeginIoStatement<ExternalMiscIoStatementState>(
400+
*unit, ExternalMiscIoStatementState::Backspace, sourceFile, sourceLine);
401+
} else {
402+
auto &io{
403+
New<NoopStatementState>{terminator}(sourceFile, sourceLine, unitNumber)
404+
.release()
405+
->ioStatementState()};
406+
io.GetIoErrorHandler().SetPendingError(IostatBadBackspaceUnit);
407+
return &io;
408+
}
402409
}
403410

404411
Cookie IONAME(BeginEndfile)(

flang/runtime/io-stmt.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ int CloseStatementState::EndIoStatement() {
287287
}
288288

289289
void NoUnitIoStatementState::CompleteOperation() {
290+
SignalPendingError();
290291
IoStatementBase::CompleteOperation();
291292
}
292293

flang/runtime/io-stmt.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,8 @@ class CloseStatementState : public ExternalIoStatementBase {
590590
CloseStatus status_{CloseStatus::Keep};
591591
};
592592

593-
// For CLOSE(bad unit), WAIT(bad unit, ID=nonzero) and INQUIRE(unconnected unit)
593+
// For CLOSE(bad unit), WAIT(bad unit, ID=nonzero), INQUIRE(unconnected unit),
594+
// and recoverable BACKSPACE(bad unit)
594595
class NoUnitIoStatementState : public IoStatementBase {
595596
public:
596597
IoStatementState &ioStatementState() { return ioStatementState_; }

flang/runtime/iostat.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ const char *IostatErrorString(int iostat) {
103103
return "WAIT(ID=nonzero) for an ID value that is not a pending operation";
104104
case IostatTooManyAsyncOps:
105105
return "Too many asynchronous operations pending on unit";
106+
case IostatBadBackspaceUnit:
107+
return "BACKSPACE on unconnected unit";
106108
default:
107109
return nullptr;
108110
}

flang/runtime/unit.cpp

-9
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,6 @@ ExternalFileUnit *ExternalFileUnit::LookUp(int unit) {
4343
return GetUnitMap().LookUp(unit);
4444
}
4545

46-
ExternalFileUnit &ExternalFileUnit::LookUpOrCrash(
47-
int unit, const Terminator &terminator) {
48-
ExternalFileUnit *file{LookUp(unit)};
49-
if (!file) {
50-
terminator.Crash("%d is not an open I/O unit number", unit);
51-
}
52-
return *file;
53-
}
54-
5546
ExternalFileUnit &ExternalFileUnit::LookUpOrCreate(
5647
int unit, const Terminator &terminator, bool &wasExtant) {
5748
return GetUnitMap().LookUpOrCreate(unit, terminator, wasExtant);

flang/runtime/unit.h

-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ class ExternalFileUnit : public ConnectionState,
4747
bool createdForInternalChildIo() const { return createdForInternalChildIo_; }
4848

4949
static ExternalFileUnit *LookUp(int unit);
50-
static ExternalFileUnit &LookUpOrCrash(int unit, const Terminator &);
5150
static ExternalFileUnit &LookUpOrCreate(
5251
int unit, const Terminator &, bool &wasExtant);
5352
static ExternalFileUnit &LookUpOrCreateAnonymous(int unit, Direction,

0 commit comments

Comments
 (0)