Skip to content

Commit 8b63eaf

Browse files
committed
[flang][runtime] Don't write implied ENDFILE for REC=/POS=
An implied ENDFILE record, which truncates an external file, should be written to a sequential unit whenever the file is repositioned for a BACKSPACE or REWIND statement if a WRITE statement has executed since the last OPEN/BACKSPACE/REWIND. But the REC= and POS= positioning specifiers don't apply to sequential units (they're for direct and stream units, resp.), so don't truncate the file when they're used.
1 parent 69cb99f commit 8b63eaf

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

flang/runtime/unit.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,7 @@ void ExternalFileUnit::Rewind(IoErrorHandler &handler) {
679679
handler.SignalError(IostatRewindNonSequential,
680680
"REWIND(UNIT=%d) on non-sequential file", unitNumber());
681681
} else {
682+
DoImpliedEndfile(handler);
682683
SetPosition(0, handler);
683684
currentRecordNumber = 1;
684685
leftTabLimit.reset();
@@ -687,7 +688,6 @@ void ExternalFileUnit::Rewind(IoErrorHandler &handler) {
687688
}
688689

689690
void ExternalFileUnit::SetPosition(std::int64_t pos, IoErrorHandler &handler) {
690-
DoImpliedEndfile(handler);
691691
frameOffsetInFile_ = pos;
692692
recordOffsetInFrame_ = 0;
693693
if (access == Access::Direct) {
@@ -707,6 +707,12 @@ bool ExternalFileUnit::SetStreamPos(
707707
"POS=%zd is invalid", static_cast<std::intmax_t>(oneBasedPos));
708708
return false;
709709
}
710+
// A backwards POS= implies truncation after writing, at least in
711+
// Intel and NAG.
712+
if (static_cast<std::size_t>(oneBasedPos - 1) <
713+
frameOffsetInFile_ + recordOffsetInFrame_) {
714+
DoImpliedEndfile(handler);
715+
}
710716
SetPosition(oneBasedPos - 1, handler);
711717
// We no longer know which record we're in. Set currentRecordNumber to
712718
// a large value from whence we can both advance and backspace.

0 commit comments

Comments
 (0)