mirror of
https://github.com/intel/llvm.git
synced 2026-02-08 00:50:03 +08:00
[flang][runtime] When OPEN implies CLOSE, disable later extant unit c… (#69390)
…hecks An OPEN statement on an existing unit can imply a CLOSE of that unit; for example, OPEN(5, FILE="mydata", FORM="formatted") should implicitly close the standard input that had been preconnected to unit 5. When this happens, later checks in OPEN statement completion that apply only to existing units should be disabled.
This commit is contained in:
@@ -248,8 +248,10 @@ void OpenStatementState::CompleteOperation() {
|
||||
}
|
||||
if (path_.get() || wasExtant_ ||
|
||||
(status_ && *status_ == OpenStatus::Scratch)) {
|
||||
unit().OpenUnit(status_, action_, position_.value_or(Position::AsIs),
|
||||
std::move(path_), pathLength_, convert_, *this);
|
||||
if (unit().OpenUnit(status_, action_, position_.value_or(Position::AsIs),
|
||||
std::move(path_), pathLength_, convert_, *this)) {
|
||||
wasExtant_ = false; // existing unit was closed
|
||||
}
|
||||
} else {
|
||||
unit().OpenAnonymousUnit(
|
||||
status_, action_, position_.value_or(Position::AsIs), convert_, *this);
|
||||
|
||||
@@ -90,7 +90,7 @@ ExternalFileUnit &ExternalFileUnit::NewUnit(
|
||||
return unit;
|
||||
}
|
||||
|
||||
void ExternalFileUnit::OpenUnit(std::optional<OpenStatus> status,
|
||||
bool ExternalFileUnit::OpenUnit(std::optional<OpenStatus> status,
|
||||
std::optional<Action> action, Position position, OwningPtr<char> &&newPath,
|
||||
std::size_t newPathLength, Convert convert, IoErrorHandler &handler) {
|
||||
if (convert == Convert::Unknown) {
|
||||
@@ -99,24 +99,26 @@ void ExternalFileUnit::OpenUnit(std::optional<OpenStatus> status,
|
||||
swapEndianness_ = convert == Convert::Swap ||
|
||||
(convert == Convert::LittleEndian && !isHostLittleEndian) ||
|
||||
(convert == Convert::BigEndian && isHostLittleEndian);
|
||||
bool impliedClose{false};
|
||||
if (IsConnected()) {
|
||||
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;
|
||||
return impliedClose;
|
||||
}
|
||||
if (!newPath.get() || isSamePath) {
|
||||
// OPEN of existing unit, STATUS='OLD' or unspecified, not new FILE=
|
||||
newPath.reset();
|
||||
return;
|
||||
return impliedClose;
|
||||
}
|
||||
// Otherwise, OPEN on open unit with new FILE= implies CLOSE
|
||||
DoImpliedEndfile(handler);
|
||||
FlushOutput(handler);
|
||||
TruncateFrame(0, handler);
|
||||
Close(CloseStatus::Keep, handler);
|
||||
impliedClose = true;
|
||||
}
|
||||
if (newPath.get() && newPathLength > 0) {
|
||||
if (const auto *already{
|
||||
@@ -125,7 +127,7 @@ void ExternalFileUnit::OpenUnit(std::optional<OpenStatus> status,
|
||||
"OPEN(UNIT=%d,FILE='%.*s'): file is already connected to unit %d",
|
||||
unitNumber_, static_cast<int>(newPathLength), newPath.get(),
|
||||
already->unitNumber_);
|
||||
return;
|
||||
return impliedClose;
|
||||
}
|
||||
}
|
||||
set_path(std::move(newPath), newPathLength);
|
||||
@@ -166,6 +168,7 @@ void ExternalFileUnit::OpenUnit(std::optional<OpenStatus> status,
|
||||
currentRecordNumber = *endfileRecordNumber;
|
||||
}
|
||||
}
|
||||
return impliedClose;
|
||||
}
|
||||
|
||||
void ExternalFileUnit::OpenAnonymousUnit(std::optional<OpenStatus> status,
|
||||
|
||||
@@ -59,7 +59,8 @@ public:
|
||||
static void CloseAll(IoErrorHandler &);
|
||||
static void FlushAll(IoErrorHandler &);
|
||||
|
||||
void OpenUnit(std::optional<OpenStatus>, std::optional<Action>, Position,
|
||||
// Returns true if an existing unit was closed
|
||||
bool OpenUnit(std::optional<OpenStatus>, std::optional<Action>, Position,
|
||||
OwningPtr<char> &&path, std::size_t pathLength, Convert,
|
||||
IoErrorHandler &);
|
||||
void OpenAnonymousUnit(std::optional<OpenStatus>, std::optional<Action>,
|
||||
|
||||
Reference in New Issue
Block a user