From b77fd01a8f4423d2ed0868fb53e5588fe6791cd4 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Wed, 5 Jan 2022 11:42:18 -0800 Subject: [PATCH] [flang] Don't blank-fill remaining lines in internal output Internal writes to character arrays should not blank-fill records (elements) past the last one that was written to. Differential Revision: https://reviews.llvm.org/D117342 --- flang/runtime/internal-unit.cpp | 28 +++++++++---------- flang/runtime/internal-unit.h | 2 ++ .../unittests/Runtime/NumericalFormatTest.cpp | 5 +++- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/flang/runtime/internal-unit.cpp b/flang/runtime/internal-unit.cpp index e63b2149793f1..7842cfb2e4494 100644 --- a/flang/runtime/internal-unit.cpp +++ b/flang/runtime/internal-unit.cpp @@ -38,15 +38,9 @@ InternalDescriptorUnit::InternalDescriptorUnit( } template void InternalDescriptorUnit::EndIoStatement() { - if constexpr (DIR == Direction::Output) { // blank fill - while (char *record{CurrentRecord()}) { - if (furthestPositionInRecord < - recordLength.value_or(furthestPositionInRecord)) { - std::fill_n(record + furthestPositionInRecord, - *recordLength - furthestPositionInRecord, ' '); - } - furthestPositionInRecord = 0; - ++currentRecordNumber; + if constexpr (DIR == Direction::Output) { + if (furthestPositionInRecord > 0) { + BlankFillOutputRecord(); } } } @@ -127,18 +121,24 @@ bool InternalDescriptorUnit::AdvanceRecord(IoErrorHandler &handler) { handler.SignalEnd(); return false; } - if constexpr (DIR == Direction::Output) { // blank fill + if constexpr (DIR == Direction::Output) { + BlankFillOutputRecord(); + } + ++currentRecordNumber; + BeginRecord(); + return true; +} + +template +void InternalDescriptorUnit::BlankFillOutputRecord() { + if constexpr (DIR == Direction::Output) { if (furthestPositionInRecord < recordLength.value_or(furthestPositionInRecord)) { char *record{CurrentRecord()}; - RUNTIME_CHECK(handler, record != nullptr); std::fill_n(record + furthestPositionInRecord, *recordLength - furthestPositionInRecord, ' '); } } - ++currentRecordNumber; - BeginRecord(); - return true; } template diff --git a/flang/runtime/internal-unit.h b/flang/runtime/internal-unit.h index 9fc9c86bd2ccf..ad52cc761de53 100644 --- a/flang/runtime/internal-unit.h +++ b/flang/runtime/internal-unit.h @@ -45,6 +45,8 @@ template class InternalDescriptorUnit : public ConnectionState { return descriptor().template ZeroBasedIndexedElement( currentRecordNumber - 1); } + void BlankFillOutputRecord(); + StaticDescriptor staticDescriptor_; }; diff --git a/flang/unittests/Runtime/NumericalFormatTest.cpp b/flang/unittests/Runtime/NumericalFormatTest.cpp index a2bd63524cb95..5a99625a1f382 100644 --- a/flang/unittests/Runtime/NumericalFormatTest.cpp +++ b/flang/unittests/Runtime/NumericalFormatTest.cpp @@ -118,6 +118,9 @@ TEST(IOApiTests, MultilineOutputTest) { auto cookie{IONAME(BeginInternalArrayFormattedOutput)( section, format, std::strlen(format))}; + // Fill last line with periods + std::memset(buffer[numLines - 1], '.', lineLength); + // Write data to buffer IONAME(OutputAscii)(cookie, "WORLD", 5); IONAME(OutputAscii)(cookie, "HELLO", 5); @@ -135,7 +138,7 @@ TEST(IOApiTests, MultilineOutputTest) { " " "789 abcd 666 777" " 888 999 " - " "}; + "................................"}; // Ensure formatted string matches expected output EXPECT_TRUE( CompareFormattedStrings(expect, std::string{buffer[0], sizeof buffer}))