Skip to content

Commit

Permalink
[flang] Fix edge-case I/O regressions
Browse files Browse the repository at this point in the history
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
  • Loading branch information
klausler committed Feb 2, 2022
1 parent b6e048c commit 0f5c60f
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 10 deletions.
23 changes: 14 additions & 9 deletions flang/runtime/edit-input.cpp
Expand Up @@ -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') {
Expand All @@ -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;
}
Expand Down Expand Up @@ -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)};
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion flang/runtime/internal-unit.cpp
Expand Up @@ -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();
}
}
Expand Down

0 comments on commit 0f5c60f

Please sign in to comment.