diff --git a/flang/runtime/io-api.cpp b/flang/runtime/io-api.cpp --- a/flang/runtime/io-api.cpp +++ b/flang/runtime/io-api.cpp @@ -268,9 +268,9 @@ IoErrorHandler handler{terminator}; unit.SetDirection(DIR, handler); if constexpr (DIR == Direction::Output) { - if (unit.access == Access::Sequential && !unit.isFixedRecordLength) { + if (unit.access == Access::Sequential) { // Create space for (sub)record header to be completed by - // ExternalUnformattedIoStatementState::EndIoStatement() + // ExternalFileUnit::AdvanceRecord() unit.recordLength.reset(); // in case of prior BACKSPACE io.Emit("\0\0\0\0", 4); // placeholder for record length header } diff --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp --- a/flang/runtime/unit.cpp +++ b/flang/runtime/unit.cpp @@ -375,7 +375,7 @@ if (access == Access::Sequential) { if (endfileRecordNumber && currentRecordNumber >= *endfileRecordNumber) { handler.SignalEnd(); - } else if (isFixedRecordLength) { + } else if (isFixedRecordLength && access == Access::Direct) { RUNTIME_CHECK(handler, recordLength.has_value()); auto need{ static_cast(recordOffsetInFrame_ + *recordLength)}; @@ -406,7 +406,7 @@ // avoid bogus crashes in END/ERR circumstances } else if (access == Access::Sequential) { RUNTIME_CHECK(handler, recordLength.has_value()); - if (isFixedRecordLength) { + if (isFixedRecordLength && access == Access::Direct) { frameOffsetInFile_ += recordOffsetInFrame_ + *recordLength; recordOffsetInFrame_ = 0; } else { @@ -444,17 +444,17 @@ } else { // Direction::Output bool ok{true}; RUNTIME_CHECK(handler, isUnformatted.has_value()); - if (isFixedRecordLength && recordLength) { + if (isFixedRecordLength && recordLength && + furthestPositionInRecord < *recordLength) { // Pad remainder of fixed length record - if (furthestPositionInRecord < *recordLength) { - WriteFrame( - frameOffsetInFile_, recordOffsetInFrame_ + *recordLength, handler); - std::memset(Frame() + recordOffsetInFrame_ + furthestPositionInRecord, - isUnformatted.value_or(false) ? 0 : ' ', - *recordLength - furthestPositionInRecord); - } - } else { - positionInRecord = furthestPositionInRecord; + WriteFrame( + frameOffsetInFile_, recordOffsetInFrame_ + *recordLength, handler); + std::memset(Frame() + recordOffsetInFrame_ + furthestPositionInRecord, + isUnformatted.value_or(false) ? 0 : ' ', + *recordLength - furthestPositionInRecord); + furthestPositionInRecord = *recordLength; + } + if (!(isFixedRecordLength && access == Access::Direct)) { if (isUnformatted.value_or(false)) { // Append the length of a sequential unformatted variable-length record // as its footer, then overwrite the reserved first four bytes of the @@ -464,6 +464,7 @@ // headers &/or footers std::uint32_t length; length = furthestPositionInRecord - sizeof length; + positionInRecord = furthestPositionInRecord; ok = ok && Emit(reinterpret_cast(&length), sizeof length, sizeof length, handler); @@ -498,7 +499,7 @@ DoImpliedEndfile(handler); if (frameOffsetInFile_ + recordOffsetInFrame_ > 0) { --currentRecordNumber; - if (isFixedRecordLength) { + if (isFixedRecordLength && access == Access::Direct) { BackspaceFixedRecord(handler); } else { RUNTIME_CHECK(handler, isUnformatted.has_value());