Skip to content

Commit 8527f9e

Browse files
committed
[flang][runtime] Handle BACKSPACE after reading past EOF
An external READ(END=) that hits the end of the file must also note the virtual position of the endfile record that has just been discovered, so that a later BACKSPACE statement won't end up at the wrong record. Differential Revision: https://reviews.llvm.org/D126146
1 parent c8644ea commit 8527f9e

File tree

2 files changed

+13
-11
lines changed

2 files changed

+13
-11
lines changed

flang/runtime/unit.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -348,10 +348,7 @@ bool ExternalFileUnit::Receive(char *data, std::size_t bytes,
348348
furthestPositionInRecord = furthestAfter;
349349
return true;
350350
} else {
351-
handler.SignalEnd();
352-
if (IsRecordFile() && access != Access::Direct) {
353-
endfileRecordNumber = currentRecordNumber;
354-
}
351+
HitEndOnRead(handler);
355352
return false;
356353
}
357354
}
@@ -384,10 +381,7 @@ const char *ExternalFileUnit::FrameNextInput(
384381
if (got >= need) {
385382
return Frame() + at;
386383
}
387-
handler.SignalEnd();
388-
if (IsRecordFile() && access != Access::Direct) {
389-
endfileRecordNumber = currentRecordNumber;
390-
}
384+
HitEndOnRead(handler);
391385
}
392386
return nullptr;
393387
}
@@ -422,7 +416,7 @@ bool ExternalFileUnit::BeginReadingRecord(IoErrorHandler &handler) {
422416
recordLength = openRecl;
423417
} else {
424418
recordLength.reset();
425-
handler.SignalEnd();
419+
HitEndOnRead(handler);
426420
}
427421
} else {
428422
recordLength.reset();
@@ -667,7 +661,7 @@ void ExternalFileUnit::BeginSequentialVariableUnformattedInputRecord(
667661
const char *error{nullptr};
668662
if (got < need) {
669663
if (got == recordOffsetInFrame_) {
670-
handler.SignalEnd();
664+
HitEndOnRead(handler);
671665
} else {
672666
error = "Unformatted variable-length sequential file input failed at "
673667
"record #%jd (file offset %jd): truncated record header";
@@ -722,7 +716,7 @@ void ExternalFileUnit::BeginVariableFormattedInputRecord(
722716
recordLength = length;
723717
unterminatedRecord = true;
724718
} else {
725-
handler.SignalEnd();
719+
HitEndOnRead(handler);
726720
}
727721
break;
728722
}
@@ -878,6 +872,13 @@ bool ExternalFileUnit::CheckDirectAccess(IoErrorHandler &handler) {
878872
return true;
879873
}
880874

875+
void ExternalFileUnit::HitEndOnRead(IoErrorHandler &handler) {
876+
handler.SignalEnd();
877+
if (IsRecordFile() && access != Access::Direct) {
878+
endfileRecordNumber = currentRecordNumber;
879+
}
880+
}
881+
881882
ChildIo &ExternalFileUnit::PushChildIo(IoStatementState &parent) {
882883
OwningPtr<ChildIo> current{std::move(child_)};
883884
Terminator &terminator{parent.GetIoErrorHandler()};

flang/runtime/unit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ class ExternalFileUnit : public ConnectionState,
115115
void DoEndfile(IoErrorHandler &);
116116
void CommitWrites();
117117
bool CheckDirectAccess(IoErrorHandler &);
118+
void HitEndOnRead(IoErrorHandler &);
118119

119120
int unitNumber_{-1};
120121
Direction direction_{Direction::Output};

0 commit comments

Comments
 (0)