[flang-commits] [flang] 0f5c60f - [flang] Fix edge-case I/O regressions
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Tue Feb 1 16:27:56 PST 2022
Author: Peter Klausler
Date: 2022-02-01T16:27:47-08:00
New Revision: 0f5c60f151e1991a7880cfc5311f7b1c61ce1528
URL: https://github.com/llvm/llvm-project/commit/0f5c60f151e1991a7880cfc5311f7b1c61ce1528
DIFF: https://github.com/llvm/llvm-project/commit/0f5c60f151e1991a7880cfc5311f7b1c61ce1528.diff
LOG: [flang] Fix edge-case I/O regressions
A blank field in an input record that exists must be interpreted
as a zero value for numeric input editing, but advancing to a
next record that doesn't exist should leave an input variable
unmodified (and signal END=). On internal output, blank fill
the "current record" array element even if nothing has been
written to it if it is the only record.
Differential Revision: https://reviews.llvm.org/D118720
Added:
Modified:
flang/runtime/edit-input.cpp
flang/runtime/internal-unit.cpp
Removed:
################################################################################
diff --git a/flang/runtime/edit-input.cpp b/flang/runtime/edit-input.cpp
index dff79841cf18c..3460661cc4270 100644
--- a/flang/runtime/edit-input.cpp
+++ b/flang/runtime/edit-input.cpp
@@ -99,8 +99,8 @@ bool EditIntegerInput(
std::optional<int> remaining;
std::optional<char32_t> next;
bool negate{ScanNumericPrefix(io, edit, next, remaining)};
- common::UnsignedInt128 value;
- bool any{false};
+ common::UnsignedInt128 value{0};
+ bool any{negate};
for (; next; next = io.NextInField(remaining)) {
char32_t ch{*next};
if (ch == ' ' || ch == '\t') {
@@ -122,11 +122,11 @@ bool EditIntegerInput(
value += digit;
any = true;
}
- if (any) {
- if (negate) {
- value = -value;
- }
- std::memcpy(n, &value, kind);
+ if (negate) {
+ value = -value;
+ }
+ if (any || !io.GetConnectionState().IsAtEOF()) {
+ std::memcpy(n, &value, kind); // a blank field means zero
}
return any;
}
@@ -155,7 +155,9 @@ static int ScanRealInput(char *buffer, int bufferSize, IoStatementState &io,
}
if (next.value_or(' ') == ' ') { // empty/blank field means zero
remaining.reset();
- Put('0');
+ if (!io.GetConnectionState().IsAtEOF()) {
+ Put('0');
+ }
return got;
}
char32_t decimal{GetDecimalPoint(edit)};
@@ -524,7 +526,7 @@ static bool EditListDirectedDefaultCharacterInput(
io.HandleRelativePosition(1);
return EditDelimitedCharacterInput(io, x, length, *ch);
}
- if (IsNamelistName(io)) {
+ if (IsNamelistName(io) || io.GetConnectionState().IsAtEOF()) {
return false;
}
// Undelimited list-directed character input: stop at a value separator
@@ -563,6 +565,9 @@ bool EditDefaultCharacterInput(
edit.descriptor);
return false;
}
+ if (io.GetConnectionState().IsAtEOF()) {
+ return false;
+ }
std::optional<int> remaining{length};
if (edit.width && *edit.width > 0) {
remaining = *edit.width;
diff --git a/flang/runtime/internal-unit.cpp b/flang/runtime/internal-unit.cpp
index 7842cfb2e4494..0c833ba548ec7 100644
--- a/flang/runtime/internal-unit.cpp
+++ b/flang/runtime/internal-unit.cpp
@@ -39,7 +39,9 @@ InternalDescriptorUnit<DIR>::InternalDescriptorUnit(
template <Direction DIR> void InternalDescriptorUnit<DIR>::EndIoStatement() {
if constexpr (DIR == Direction::Output) {
- if (furthestPositionInRecord > 0) {
+ // Clear the remainder of the current record if anything was written
+ // to it, or if it is the only record.
+ if (endfileRecordNumber.value_or(-1) == 2 || furthestPositionInRecord > 0) {
BlankFillOutputRecord();
}
}
More information about the flang-commits
mailing list