[flang-commits] [flang] f651bbe - [flang] Correct interpretation of RECL=
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Mon Jan 31 12:48:24 PST 2022
Author: Peter Klausler
Date: 2022-01-31T12:48:17-08:00
New Revision: f651bbea0692bef2249c92174796ace873fbe89a
URL: https://github.com/llvm/llvm-project/commit/f651bbea0692bef2249c92174796ace873fbe89a
DIFF: https://github.com/llvm/llvm-project/commit/f651bbea0692bef2249c92174796ace873fbe89a.diff
LOG: [flang] Correct interpretation of RECL=
When RECL= is set on OPEN(), ensure that it:
1) enforces a max output record payload size
(not including header+footer or newline), and
2) causes padding of short output records only
for ACCESS='DIRECT'
The previous code was causing some false overrun errors
and applying padding to sequential/stream output files.
Differential Revision: https://reviews.llvm.org/D118630
Added:
Modified:
flang/runtime/unit.cpp
Removed:
################################################################################
diff --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp
index e24e1b9ae64c..363565da6833 100644
--- a/flang/runtime/unit.cpp
+++ b/flang/runtime/unit.cpp
@@ -279,16 +279,23 @@ bool ExternalFileUnit::Emit(const char *data, std::size_t bytes,
positionInRecord + static_cast<std::int64_t>(bytes))};
if (openRecl) {
// Check for fixed-length record overrun, but allow for
- // the unformatted sequential record header & footer, if any.
- int extra{access == Access::Sequential && isUnformatted && *isUnformatted
- ? static_cast<int>(sizeof(std::uint32_t))
- : 0};
- if (furthestAfter > 2 * extra + *openRecl) {
+ // sequential record termination.
+ int extra{0};
+ int header{0};
+ if (access == Access::Sequential) {
+ if (isUnformatted.value_or(false)) {
+ // record header + footer
+ header = static_cast<int>(sizeof(std::uint32_t));
+ extra = 2 * header;
+ } else {
+ extra = 1; // newline
+ }
+ }
+ if (furthestAfter > extra + *openRecl) {
handler.SignalError(IostatRecordWriteOverrun,
"Attempt to write %zd bytes to position %jd in a fixed-size record "
"of %jd bytes",
- bytes,
- static_cast<std::intmax_t>(positionInRecord - extra /*header*/),
+ bytes, static_cast<std::intmax_t>(positionInRecord - header),
static_cast<std::intmax_t>(*openRecl));
return false;
}
@@ -487,15 +494,17 @@ bool ExternalFileUnit::AdvanceRecord(IoErrorHandler &handler) {
} else { // Direction::Output
bool ok{true};
RUNTIME_CHECK(handler, isUnformatted.has_value());
- if (openRecl && furthestPositionInRecord < *openRecl) {
- // Pad remainder of fixed length record
- WriteFrame(frameOffsetInFile_, recordOffsetInFrame_ + *openRecl, handler);
- std::memset(Frame() + recordOffsetInFrame_ + furthestPositionInRecord,
- isUnformatted.value_or(false) ? 0 : ' ',
- *openRecl - furthestPositionInRecord);
- furthestPositionInRecord = *openRecl;
- }
- if (!(openRecl && access == Access::Direct)) {
+ if (openRecl && access == Access::Direct) {
+ if (furthestPositionInRecord < *openRecl) {
+ // Pad remainder of fixed length record
+ WriteFrame(
+ frameOffsetInFile_, recordOffsetInFrame_ + *openRecl, handler);
+ std::memset(Frame() + recordOffsetInFrame_ + furthestPositionInRecord,
+ isUnformatted.value_or(false) ? 0 : ' ',
+ *openRecl - furthestPositionInRecord);
+ furthestPositionInRecord = *openRecl;
+ }
+ } else {
positionInRecord = furthestPositionInRecord;
if (isUnformatted.value_or(false)) {
// Append the length of a sequential unformatted variable-length record
More information about the flang-commits
mailing list