Skip to content

Commit 030fdc4

Browse files
klauslerjeanPerier
authored andcommitted
[flang] Emit unformatted headers & footers even with RECL=
The runtime library was emitting unformatted record headers and footers when an external unit had no fixed RECL=. This is wrong for sequential files, which should have headers & footers even with RECL. Change to omit headers & footers from unformatted I/O only for direct access files. Differential Revision: https://reviews.llvm.org/D112243
1 parent dc2267c commit 030fdc4

File tree

2 files changed

+16
-15
lines changed

2 files changed

+16
-15
lines changed

flang/runtime/io-api.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,9 +268,9 @@ Cookie BeginUnformattedIO(
268268
IoErrorHandler handler{terminator};
269269
unit.SetDirection(DIR, handler);
270270
if constexpr (DIR == Direction::Output) {
271-
if (unit.access == Access::Sequential && !unit.isFixedRecordLength) {
271+
if (unit.access == Access::Sequential) {
272272
// Create space for (sub)record header to be completed by
273-
// ExternalUnformattedIoStatementState<Direction::Output>::EndIoStatement()
273+
// ExternalFileUnit::AdvanceRecord()
274274
unit.recordLength.reset(); // in case of prior BACKSPACE
275275
io.Emit("\0\0\0\0", 4); // placeholder for record length header
276276
}

flang/runtime/unit.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ bool ExternalFileUnit::BeginReadingRecord(IoErrorHandler &handler) {
375375
if (access == Access::Sequential) {
376376
if (endfileRecordNumber && currentRecordNumber >= *endfileRecordNumber) {
377377
handler.SignalEnd();
378-
} else if (isFixedRecordLength) {
378+
} else if (isFixedRecordLength && access == Access::Direct) {
379379
RUNTIME_CHECK(handler, recordLength.has_value());
380380
auto need{
381381
static_cast<std::size_t>(recordOffsetInFrame_ + *recordLength)};
@@ -406,7 +406,7 @@ void ExternalFileUnit::FinishReadingRecord(IoErrorHandler &handler) {
406406
// avoid bogus crashes in END/ERR circumstances
407407
} else if (access == Access::Sequential) {
408408
RUNTIME_CHECK(handler, recordLength.has_value());
409-
if (isFixedRecordLength) {
409+
if (isFixedRecordLength && access == Access::Direct) {
410410
frameOffsetInFile_ += recordOffsetInFrame_ + *recordLength;
411411
recordOffsetInFrame_ = 0;
412412
} else {
@@ -444,17 +444,17 @@ bool ExternalFileUnit::AdvanceRecord(IoErrorHandler &handler) {
444444
} else { // Direction::Output
445445
bool ok{true};
446446
RUNTIME_CHECK(handler, isUnformatted.has_value());
447-
if (isFixedRecordLength && recordLength) {
447+
if (isFixedRecordLength && recordLength &&
448+
furthestPositionInRecord < *recordLength) {
448449
// Pad remainder of fixed length record
449-
if (furthestPositionInRecord < *recordLength) {
450-
WriteFrame(
451-
frameOffsetInFile_, recordOffsetInFrame_ + *recordLength, handler);
452-
std::memset(Frame() + recordOffsetInFrame_ + furthestPositionInRecord,
453-
isUnformatted.value_or(false) ? 0 : ' ',
454-
*recordLength - furthestPositionInRecord);
455-
}
456-
} else {
457-
positionInRecord = furthestPositionInRecord;
450+
WriteFrame(
451+
frameOffsetInFile_, recordOffsetInFrame_ + *recordLength, handler);
452+
std::memset(Frame() + recordOffsetInFrame_ + furthestPositionInRecord,
453+
isUnformatted.value_or(false) ? 0 : ' ',
454+
*recordLength - furthestPositionInRecord);
455+
furthestPositionInRecord = *recordLength;
456+
}
457+
if (!(isFixedRecordLength && access == Access::Direct)) {
458458
if (isUnformatted.value_or(false)) {
459459
// Append the length of a sequential unformatted variable-length record
460460
// as its footer, then overwrite the reserved first four bytes of the
@@ -464,6 +464,7 @@ bool ExternalFileUnit::AdvanceRecord(IoErrorHandler &handler) {
464464
// headers &/or footers
465465
std::uint32_t length;
466466
length = furthestPositionInRecord - sizeof length;
467+
positionInRecord = furthestPositionInRecord;
467468
ok = ok &&
468469
Emit(reinterpret_cast<const char *>(&length), sizeof length,
469470
sizeof length, handler);
@@ -498,7 +499,7 @@ void ExternalFileUnit::BackspaceRecord(IoErrorHandler &handler) {
498499
DoImpliedEndfile(handler);
499500
if (frameOffsetInFile_ + recordOffsetInFrame_ > 0) {
500501
--currentRecordNumber;
501-
if (isFixedRecordLength) {
502+
if (isFixedRecordLength && access == Access::Direct) {
502503
BackspaceFixedRecord(handler);
503504
} else {
504505
RUNTIME_CHECK(handler, isUnformatted.has_value());

0 commit comments

Comments
 (0)