diff --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp index 971909b74e769..6e6db78592783 100644 --- a/flang/runtime/unit.cpp +++ b/flang/runtime/unit.cpp @@ -310,6 +310,7 @@ bool ExternalFileUnit::Emit(const char *data, std::size_t bytes, handler.SignalError(IostatWriteAfterEndfile); return false; } + CheckDirectAccess(handler); WriteFrame(frameOffsetInFile_, recordOffsetInFrame_ + furthestAfter, handler); if (positionInRecord > furthestPositionInRecord) { std::memset(Frame() + recordOffsetInFrame_ + furthestPositionInRecord, ' ', @@ -432,7 +433,7 @@ bool ExternalFileUnit::BeginReadingRecord(IoErrorHandler &handler) { if (!beganReadingRecord_) { beganReadingRecord_ = true; if (access == Access::Direct) { - RUNTIME_CHECK(handler, openRecl); + CheckDirectAccess(handler); auto need{static_cast(recordOffsetInFrame_ + *openRecl)}; auto got{ReadFrame(frameOffsetInFile_, need, handler)}; if (got >= need) { @@ -654,6 +655,9 @@ void ExternalFileUnit::SetPosition(std::int64_t pos, IoErrorHandler &handler) { DoImpliedEndfile(handler); frameOffsetInFile_ = pos; recordOffsetInFrame_ = 0; + if (access == Access::Direct) { + directAccessRecWasSet_ = true; + } BeginRecord(); } @@ -846,6 +850,17 @@ void ExternalFileUnit::CommitWrites() { BeginRecord(); } +bool ExternalFileUnit::CheckDirectAccess(IoErrorHandler &handler) { + if (access == Access::Direct) { + RUNTIME_CHECK(handler, openRecl); + if (!directAccessRecWasSet_) { + handler.SignalError("No REC= was specified for a data transfer with ACCESS='DIRECT'"); + return false; + } + } + return true; +} + ChildIo &ExternalFileUnit::PushChildIo(IoStatementState &parent) { OwningPtr current{std::move(child_)}; Terminator &terminator{parent.GetIoErrorHandler()}; diff --git a/flang/runtime/unit.h b/flang/runtime/unit.h index c8e65c1f0c4c6..7be5e2f387f8d 100644 --- a/flang/runtime/unit.h +++ b/flang/runtime/unit.h @@ -71,6 +71,7 @@ class ExternalFileUnit : public ConnectionState, if constexpr (!std::is_same_v) { state.mutableModes() = ConnectionState::modes; } + directAccessRecWasSet_ = false; io_.emplace(state); return *io_; } @@ -112,11 +113,13 @@ class ExternalFileUnit : public ConnectionState, void DoImpliedEndfile(IoErrorHandler &); void DoEndfile(IoErrorHandler &); void CommitWrites(); + bool CheckDirectAccess(IoErrorHandler &); int unitNumber_{-1}; Direction direction_{Direction::Output}; bool impliedEndfile_{false}; // sequential/stream output has taken place bool beganReadingRecord_{false}; + bool directAccessRecWasSet_{false}; // REC= appeared Lock lock_;