diff --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp index 18590567c65eb..58ca313d9e445 100644 --- a/flang/runtime/unit.cpp +++ b/flang/runtime/unit.cpp @@ -679,6 +679,7 @@ void ExternalFileUnit::Rewind(IoErrorHandler &handler) { handler.SignalError(IostatRewindNonSequential, "REWIND(UNIT=%d) on non-sequential file", unitNumber()); } else { + DoImpliedEndfile(handler); SetPosition(0, handler); currentRecordNumber = 1; leftTabLimit.reset(); @@ -687,7 +688,6 @@ void ExternalFileUnit::Rewind(IoErrorHandler &handler) { } void ExternalFileUnit::SetPosition(std::int64_t pos, IoErrorHandler &handler) { - DoImpliedEndfile(handler); frameOffsetInFile_ = pos; recordOffsetInFrame_ = 0; if (access == Access::Direct) { @@ -707,6 +707,12 @@ bool ExternalFileUnit::SetStreamPos( "POS=%zd is invalid", static_cast(oneBasedPos)); return false; } + // A backwards POS= implies truncation after writing, at least in + // Intel and NAG. + if (static_cast(oneBasedPos - 1) < + frameOffsetInFile_ + recordOffsetInFrame_) { + DoImpliedEndfile(handler); + } SetPosition(oneBasedPos - 1, handler); // We no longer know which record we're in. Set currentRecordNumber to // a large value from whence we can both advance and backspace.