[flang][runtime] Fix formatted input of NAN(...) (#149606)

Formatted real input is allowed to have parenthesized information after
"NAN". We don't interpret the contents, but we should at least scan the
information correctly.

Fixes https://github.com/llvm/llvm-project/issues/149533 and
https://github.com/llvm/llvm-project/issues/150035.
This commit is contained in:
Peter Klausler 2025-07-25 14:47:26 -07:00 committed by GitHub
parent 1d81dfaa8f
commit f6a6cdd15c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 14 deletions

View File

@ -375,21 +375,37 @@ static RT_API_ATTRS ScannedRealInput ScanRealInput(
Put(*next);
}
}
if (next && *next == '(') { // NaN(...)
Put('(');
int depth{1};
while (true) {
next = io.NextInField(remaining, edit);
if (depth == 0) {
break;
} else if (!next) {
return {}; // error
} else if (*next == '(') {
++depth;
} else if (*next == ')') {
--depth;
if (first == 'N' && (!next || *next == '(') &&
remaining.value_or(1) > 0) { // NaN(...)?
std::size_t byteCount{0};
if (!next) { // NextInField won't return '(' for list-directed
next = io.GetCurrentChar(byteCount);
}
if (next && *next == '(') {
int depth{1};
while (true) {
if (*next >= 'a' && *next <= 'z') {
*next = *next - 'a' + 'A';
}
Put(*next);
io.HandleRelativePosition(byteCount);
io.GotChar(byteCount);
if (remaining) {
*remaining -= byteCount;
}
if (depth == 0) {
break; // done
}
next = io.GetCurrentChar(byteCount);
if (!next || remaining.value_or(1) < 1) {
return {}; // error
} else if (*next == '(') {
++depth;
} else if (*next == ')') {
--depth;
}
}
Put(*next);
next = io.NextInField(remaining, edit);
}
}
} else if (first == radixPointChar || (first >= '0' && first <= '9') ||

View File

@ -964,6 +964,7 @@ TEST(IOApiTests, EditDoubleInputValues) {
{"(RU,E9.1)", " 1.0E-325", 0x1, 0},
{"(E9.1)", "-1.0E-325", 0x8000000000000000, 0},
{"(RD,E9.1)", "-1.0E-325", 0x8000000000000001, 0},
{"(F7.0))", "+NaN(q)", 0x7ff8000000000000, 0},
};
for (auto const &[format, data, want, iostat] : testCases) {
auto cookie{IONAME(BeginInternalFormattedInput)(