Skip to content

Commit

Permalink
[flang][runtime] Fix runtime crash after bad recoverable OPEN (#111454)
Browse files Browse the repository at this point in the history
When an OPEN statement with a unit number fails in a recoverable manner,
the runtime needs to delete the ExternalFileUnit instance that was
created in the unit map. And we do this too soon -- that instance still
holds some of the I/O statement state that will be used by a later call
into the runtime for EndIoStatement.

Move the code that deletes the unit after a failed but recoverable OPEN
into ExternalIoStatementBase::EndIoStatement, and don't do things
afterwards that would need the I/O statement state that has been
destroyed.

Fixes #111404.
  • Loading branch information
klausler authored Oct 10, 2024
1 parent 3f9998a commit c893e3d
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 5 deletions.
14 changes: 9 additions & 5 deletions flang/runtime/io-stmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,15 @@ int ExternalIoStatementBase::EndIoStatement() {
CompleteOperation();
auto result{IoStatementBase::EndIoStatement()};
#if !defined(RT_USE_PSEUDO_FILE_UNIT)
auto unitNumber{unit_.unitNumber()};
unit_.EndIoStatement(); // annihilates *this in unit_.u_
if (destroy_) {
if (ExternalFileUnit *
toClose{ExternalFileUnit::LookUpForClose(unitNumber)}) {
toClose->Close(CloseStatus::Delete, *this);
toClose->DestroyClosed();
}
}
#else
// Fetch the unit pointer before *this disappears.
ExternalFileUnit *unitPtr{&unit_};
Expand Down Expand Up @@ -329,11 +337,7 @@ void OpenStatementState::CompleteOperation() {
}
if (!wasExtant_ && InError()) {
// Release the new unit on failure
if (ExternalFileUnit *
toClose{unit().LookUpForClose(unit().unitNumber())}) {
toClose->Close(CloseStatus::Delete, *this);
toClose->DestroyClosed();
}
set_destroy();
}
IoStatementBase::CompleteOperation();
}
Expand Down
2 changes: 2 additions & 0 deletions flang/runtime/io-stmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ class ExternalIoStatementBase : public IoStatementBase {
RT_API_ATTRS MutableModes &mutableModes();
RT_API_ATTRS ConnectionState &GetConnectionState();
RT_API_ATTRS int asynchronousID() const { return asynchronousID_; }
RT_API_ATTRS void set_destroy(bool yes = true) { destroy_ = yes; }
RT_API_ATTRS int EndIoStatement();
RT_API_ATTRS ExternalFileUnit *GetExternalFileUnit() const { return &unit_; }
RT_API_ATTRS void SetAsynchronous();
Expand All @@ -463,6 +464,7 @@ class ExternalIoStatementBase : public IoStatementBase {
private:
ExternalFileUnit &unit_;
int asynchronousID_{-1};
bool destroy_{false};
};

template <Direction DIR>
Expand Down

0 comments on commit c893e3d

Please sign in to comment.