Index: flang/runtime/io-stmt.cpp =================================================================== --- flang/runtime/io-stmt.cpp +++ flang/runtime/io-stmt.cpp @@ -188,17 +188,12 @@ } int OpenStatementState::EndIoStatement() { - if (wasExtant_ && status_ && *status_ != OpenStatus::Old) { - SignalError("OPEN statement for connected unit may not have STATUS= other " - "than 'OLD'"); - } if (path_.get() || wasExtant_ || (status_ && *status_ == OpenStatus::Scratch)) { - unit().OpenUnit(status_.value_or(OpenStatus::Unknown), action_, position_, - std::move(path_), pathLength_, convert_, *this); + unit().OpenUnit(status_, action_, position_, std::move(path_), pathLength_, + convert_, *this); } else { - unit().OpenAnonymousUnit(status_.value_or(OpenStatus::Unknown), action_, - position_, convert_, *this); + unit().OpenAnonymousUnit(status_, action_, position_, convert_, *this); } if (access_) { if (*access_ != unit().access) { Index: flang/runtime/unit.h =================================================================== --- flang/runtime/unit.h +++ flang/runtime/unit.h @@ -50,11 +50,11 @@ static void CloseAll(IoErrorHandler &); static void FlushAll(IoErrorHandler &); - void OpenUnit(OpenStatus, std::optional, Position, + void OpenUnit(std::optional, std::optional, Position, OwningPtr &&path, std::size_t pathLength, Convert, IoErrorHandler &); - void OpenAnonymousUnit( - OpenStatus, std::optional, Position, Convert, IoErrorHandler &); + void OpenAnonymousUnit(std::optional, std::optional, + Position, Convert, IoErrorHandler &); void CloseUnit(CloseStatus, IoErrorHandler &); void DestroyClosed(); Index: flang/runtime/unit.cpp =================================================================== --- flang/runtime/unit.cpp +++ flang/runtime/unit.cpp @@ -89,9 +89,9 @@ return GetUnitMap().NewUnit(terminator).unitNumber(); } -void ExternalFileUnit::OpenUnit(OpenStatus status, std::optional action, - Position position, OwningPtr &&newPath, std::size_t newPathLength, - Convert convert, IoErrorHandler &handler) { +void ExternalFileUnit::OpenUnit(std::optional status, + std::optional action, Position position, OwningPtr &&newPath, + std::size_t newPathLength, Convert convert, IoErrorHandler &handler) { if (executionEnvironment.conversion != Convert::Unknown) { convert = executionEnvironment.conversion; } @@ -99,11 +99,15 @@ (convert == Convert::LittleEndian && !isHostLittleEndian) || (convert == Convert::BigEndian && isHostLittleEndian); if (IsOpen()) { - if (status == OpenStatus::Old && - (!newPath.get() || - (path() && pathLength() == newPathLength && - std::memcmp(path(), newPath.get(), newPathLength) == 0))) { - // OPEN of existing unit, STATUS='OLD', not new FILE= + bool isSamePath{newPath.get() && path() && pathLength() == newPathLength && + std::memcmp(path(), newPath.get(), newPathLength) == 0}; + if (status && *status != OpenStatus::Old && isSamePath) { + handler.SignalError("OPEN statement for connected unit may not have " + "explicit STATUS= other than 'OLD'"); + return; + } + if (!newPath.get() || isSamePath) { + // OPEN of existing unit, STATUS='OLD' or unspecified, not new FILE= newPath.reset(); return; } @@ -113,7 +117,7 @@ Close(CloseStatus::Keep, handler); } set_path(std::move(newPath), newPathLength); - Open(status, action, position, handler); + Open(status.value_or(OpenStatus::Unknown), action, position, handler); auto totalBytes{knownSize()}; if (access == Access::Direct) { if (!isFixedRecordLength || !recordLength) { @@ -146,7 +150,7 @@ } } -void ExternalFileUnit::OpenAnonymousUnit(OpenStatus status, +void ExternalFileUnit::OpenAnonymousUnit(std::optional status, std::optional action, Position position, Convert convert, IoErrorHandler &handler) { // I/O to an unconnected unit reads/creates a local file, e.g. fort.7