[flang-commits] [flang] [flang][runtime] Support READ after WRITE w/o positioning (PR #74650)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Fri Dec 8 15:04:59 PST 2023
https://github.com/klausler updated https://github.com/llvm/llvm-project/pull/74650
>From ec7ac855cf996a241f085453c29fbb92ab5726d0 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Wed, 6 Dec 2023 12:00:01 -0800
Subject: [PATCH] [flang][runtime] Support READ after WRITE w/o positioning
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.
---
flang/runtime/unit.cpp | 9 +++++++++
flang/runtime/unit.h | 1 +
2 files changed, 10 insertions(+)
diff --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp
index 5fa8565c2f61f..2a25a0432a729 100644
--- a/flang/runtime/unit.cpp
+++ b/flang/runtime/unit.cpp
@@ -355,6 +355,7 @@ bool ExternalFileUnit::Emit(const char *data, std::size_t bytes,
}
positionInRecord += bytes;
furthestPositionInRecord = furthestAfter;
+ anyWriteSinceLastPositioning_ = true;
return true;
}
@@ -451,6 +452,11 @@ bool ExternalFileUnit::BeginReadingRecord(IoErrorHandler &handler) {
HitEndOnRead(handler);
}
} else {
+ if (anyWriteSinceLastPositioning_ && access == Access::Sequential) {
+ // Most Fortran implementations allow a READ after a WRITE;
+ // the read then just hits an EOF.
+ DoEndfile(handler);
+ }
recordLength.reset();
if (IsAtEOF()) {
handler.SignalEnd();
@@ -615,6 +621,7 @@ void ExternalFileUnit::BackspaceRecord(IoErrorHandler &handler) {
}
}
BeginRecord();
+ anyWriteSinceLastPositioning_ = false;
}
}
@@ -667,6 +674,7 @@ void ExternalFileUnit::Rewind(IoErrorHandler &handler) {
SetPosition(0, handler);
currentRecordNumber = 1;
leftTabLimit.reset();
+ anyWriteSinceLastPositioning_ = false;
}
}
@@ -928,6 +936,7 @@ void ExternalFileUnit::DoEndfile(IoErrorHandler &handler) {
TruncateFrame(frameOffsetInFile_, handler);
BeginRecord();
impliedEndfile_ = false;
+ anyWriteSinceLastPositioning_ = false;
}
void ExternalFileUnit::CommitWrites() {
diff --git a/flang/runtime/unit.h b/flang/runtime/unit.h
index 1ec3013ba82b3..140fda3c4d2a8 100644
--- a/flang/runtime/unit.h
+++ b/flang/runtime/unit.h
@@ -140,6 +140,7 @@ class ExternalFileUnit : public ConnectionState,
Direction direction_{Direction::Output};
bool impliedEndfile_{false}; // sequential/stream output has taken place
bool beganReadingRecord_{false};
+ bool anyWriteSinceLastPositioning_{false};
bool directAccessRecWasSet_{false}; // REC= appeared
// Subtle: The beginning of the frame can't be allowed to advance
// during a single list-directed READ due to the possibility of a
More information about the flang-commits
mailing list