Skip to content

Commit b626053

Browse files
authored
[flang][runtime] Terminate last partial record after non-advancing write (#74524)
After a non-advancing WRITE to a unit, ensure that any ENDFILE operation (explicit or implicit) terminates the record. (All other Fortran implementations do so except XLF.) Fixes llvm-test-suite/Fortran/gfortran/regression/advance_6.f90.
1 parent 1366221 commit b626053

File tree

1 file changed

+16
-15
lines changed

1 file changed

+16
-15
lines changed

flang/runtime/unit.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -595,8 +595,8 @@ void ExternalFileUnit::BackspaceRecord(IoErrorHandler &handler) {
595595
if (IsAfterEndfile()) {
596596
// BACKSPACE after explicit ENDFILE
597597
currentRecordNumber = *endfileRecordNumber;
598-
} else if (leftTabLimit) {
599-
// BACKSPACE after non-advancing I/O
598+
} else if (leftTabLimit && direction_ == Direction::Input) {
599+
// BACKSPACE after non-advancing input
600600
leftTabLimit.reset();
601601
} else {
602602
DoImpliedEndfile(handler);
@@ -896,28 +896,29 @@ void ExternalFileUnit::BackspaceVariableFormattedRecord(
896896
}
897897

898898
void ExternalFileUnit::DoImpliedEndfile(IoErrorHandler &handler) {
899-
if (!impliedEndfile_ && direction_ == Direction::Output && IsRecordFile() &&
900-
access != Access::Direct && leftTabLimit) {
901-
// Complete partial record after non-advancing write before
902-
// positioning or closing the unit. Usually sets impliedEndfile_.
903-
AdvanceRecord(handler);
904-
}
905-
if (impliedEndfile_) {
906-
impliedEndfile_ = false;
907-
if (access != Access::Direct && IsRecordFile() && mayPosition()) {
899+
if (access != Access::Direct) {
900+
if (!impliedEndfile_ && leftTabLimit && direction_ == Direction::Output) {
901+
// Flush a partial record after non-advancing output
902+
impliedEndfile_ = true;
903+
}
904+
if (impliedEndfile_ && mayPosition()) {
908905
DoEndfile(handler);
909906
}
910907
}
908+
impliedEndfile_ = false;
911909
}
912910

913911
void ExternalFileUnit::DoEndfile(IoErrorHandler &handler) {
914912
if (IsRecordFile() && access != Access::Direct) {
915913
furthestPositionInRecord =
916914
std::max(positionInRecord, furthestPositionInRecord);
917-
if (leftTabLimit) {
918-
// Last read/write was non-advancing, so AdvanceRecord() was not called.
919-
leftTabLimit.reset();
920-
++currentRecordNumber;
915+
if (leftTabLimit) { // last I/O was non-advancing
916+
if (access == Access::Sequential && direction_ == Direction::Output) {
917+
AdvanceRecord(handler);
918+
} else { // Access::Stream or input
919+
leftTabLimit.reset();
920+
++currentRecordNumber;
921+
}
921922
}
922923
endfileRecordNumber = currentRecordNumber;
923924
}

0 commit comments

Comments
 (0)