Skip to content

Commit c94f780

Browse files
authored
[flang][runtime] Support READ after WRITE w/o positioning (#74650)
Most Fortran implementations support a READ statement after a WRITE without repositioning on a sequential unit; it implies on ENDFILE and then hits an EOF condition. Fixes llvm-test-suite/Fortran/gfortran/regression/backspace_2.f.
1 parent 1cc5431 commit c94f780

File tree

2 files changed

+10
-0
lines changed

2 files changed

+10
-0
lines changed

flang/runtime/unit.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ bool ExternalFileUnit::Emit(const char *data, std::size_t bytes,
355355
}
356356
positionInRecord += bytes;
357357
furthestPositionInRecord = furthestAfter;
358+
anyWriteSinceLastPositioning_ = true;
358359
return true;
359360
}
360361

@@ -459,6 +460,11 @@ bool ExternalFileUnit::BeginReadingRecord(IoErrorHandler &handler) {
459460
HitEndOnRead(handler);
460461
}
461462
} else {
463+
if (anyWriteSinceLastPositioning_ && access == Access::Sequential) {
464+
// Most Fortran implementations allow a READ after a WRITE;
465+
// the read then just hits an EOF.
466+
DoEndfile(handler);
467+
}
462468
recordLength.reset();
463469
RUNTIME_CHECK(handler, isUnformatted.has_value());
464470
if (*isUnformatted) {
@@ -619,6 +625,7 @@ void ExternalFileUnit::BackspaceRecord(IoErrorHandler &handler) {
619625
}
620626
}
621627
BeginRecord();
628+
anyWriteSinceLastPositioning_ = false;
622629
}
623630
}
624631

@@ -671,6 +678,7 @@ void ExternalFileUnit::Rewind(IoErrorHandler &handler) {
671678
SetPosition(0, handler);
672679
currentRecordNumber = 1;
673680
leftTabLimit.reset();
681+
anyWriteSinceLastPositioning_ = false;
674682
}
675683
}
676684

@@ -934,6 +942,7 @@ void ExternalFileUnit::DoEndfile(IoErrorHandler &handler) {
934942
TruncateFrame(frameOffsetInFile_, handler);
935943
BeginRecord();
936944
impliedEndfile_ = false;
945+
anyWriteSinceLastPositioning_ = false;
937946
}
938947

939948
void ExternalFileUnit::CommitWrites() {

flang/runtime/unit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ class ExternalFileUnit : public ConnectionState,
140140
Direction direction_{Direction::Output};
141141
bool impliedEndfile_{false}; // sequential/stream output has taken place
142142
bool beganReadingRecord_{false};
143+
bool anyWriteSinceLastPositioning_{false};
143144
bool directAccessRecWasSet_{false}; // REC= appeared
144145
// Subtle: The beginning of the frame can't be allowed to advance
145146
// during a single list-directed READ due to the possibility of a

0 commit comments

Comments
 (0)