diff options
author | Peter Klausler <pklausler@nvidia.com> | 2025-08-05 13:39:33 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-05 13:39:33 -0700 |
commit | effa35d240f34bcd07f0653b6fbdd999a5dbf02e (patch) | |
tree | 1fab4cce061fc7b8f5194eb12b8275ac338d376d | |
parent | aec90f2f27317dbb075a5a816e11b4892f035680 (diff) | |
download | llvm-effa35d240f34bcd07f0653b6fbdd999a5dbf02e.zip llvm-effa35d240f34bcd07f0653b6fbdd999a5dbf02e.tar.gz llvm-effa35d240f34bcd07f0653b6fbdd999a5dbf02e.tar.bz2 |
[flang][runtime] Don't always accept a bare exponent letter (#151597)
For more accurate compatibility with other compilers' extensions, accept
a bare exponent letter as valid real input to a formatted READ statement
only in a fixed-width input field. So it works with (G1.0) editing, but
not (G)/(D)/(E)/(F) or list-directed input.
Fixes https://github.com/llvm/llvm-project/issues/151465.
-rw-r--r-- | flang-rt/lib/runtime/edit-input.cpp | 13 | ||||
-rw-r--r-- | flang-rt/unittests/Runtime/NumericalFormatTest.cpp | 9 | ||||
-rw-r--r-- | flang/docs/Extensions.md | 5 |
3 files changed, 21 insertions, 6 deletions
diff --git a/flang-rt/lib/runtime/edit-input.cpp b/flang-rt/lib/runtime/edit-input.cpp index 3a8abf3..80cc085 100644 --- a/flang-rt/lib/runtime/edit-input.cpp +++ b/flang-rt/lib/runtime/edit-input.cpp @@ -396,8 +396,9 @@ static RT_API_ATTRS ScannedRealInput ScanRealInput( } } } else if (first == radixPointChar || (first >= '0' && first <= '9') || - (bzMode && (first == ' ' || first == '\t')) || first == 'E' || - first == 'D' || first == 'Q') { + (bzMode && (first == ' ' || first == '\t')) || + (remaining.has_value() && + (first == 'D' || first == 'E' || first == 'Q'))) { if (first == '0') { next = io.NextInField(remaining, edit); if (next && (*next == 'x' || *next == 'X')) { // 0X... @@ -462,6 +463,14 @@ static RT_API_ATTRS ScannedRealInput ScanRealInput( // optional exponent letter and the exponent value. io.SkipSpaces(remaining); next = io.NextInField(remaining, edit); + if (!next) { + if (remaining.has_value()) { + // bare exponent letter accepted in fixed-width field + hasGoodExponent = true; + } else { + return {}; // error + } + } } } if (next && diff --git a/flang-rt/unittests/Runtime/NumericalFormatTest.cpp b/flang-rt/unittests/Runtime/NumericalFormatTest.cpp index 4e5fdcc..033002c 100644 --- a/flang-rt/unittests/Runtime/NumericalFormatTest.cpp +++ b/flang-rt/unittests/Runtime/NumericalFormatTest.cpp @@ -965,7 +965,10 @@ 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}, + {"(F7.0)", "+NaN(q)", 0x7ff8000000000000, 0}, + {"(G)", "D", 0, IostatBadRealInput}, + {"(G0)", "D", 0, IostatErrorInFormat}, + {"(G1.0)", "D", 0, 0}, }; for (auto const &[format, data, want, iostat] : testCases) { auto cookie{IONAME(BeginInternalFormattedInput)( @@ -988,13 +991,13 @@ TEST(IOApiTests, EditDoubleInputValues) { // union value IONAME(GetIoMsg)(cookie, iomsg, bufferSize - 1); auto status{IONAME(EndIoStatement)(cookie)}; - ASSERT_EQ(status, iostat) + EXPECT_EQ(status, iostat) << '\'' << format << "' failed reading '" << data << "', status " << static_cast<int>(status) << " != expected " << iostat << " iomsg '" << iomsg << "'"; // Ensure raw uint64 value matches expected conversion from double - ASSERT_EQ(u.raw, want) << '\'' << format << "' failed reading '" << data + EXPECT_EQ(u.raw, want) << '\'' << format << "' failed reading '" << data << "', want " << want << ", got " << u.raw; } } diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md index d697842..11c6717 100644 --- a/flang/docs/Extensions.md +++ b/flang/docs/Extensions.md @@ -479,6 +479,9 @@ end * Old-style `PARAMETER pi=3.14` statement without parentheses [-falternative-parameter-statement] * `UNSIGNED` type (-funsigned) +* Default exponent of zero, e.g. `3.14159E`, on a READ from a + fixed-width input field. Includes the case with only an + exponent letter for compatibility with other compilers. ### Extensions and legacy features deliberately not supported @@ -492,7 +495,7 @@ end * `VIRTUAL` as synonym for `DIMENSION` * `ENCODE` and `DECODE` as synonyms for internal I/O * `IMPLICIT AUTOMATIC`, `IMPLICIT STATIC` -* Default exponent of zero, e.g. `3.14159E` +* Default exponent of zero, e.g. `3.14159E`, on a literal constant * Characters in defined operators that are neither letters nor digits * `B` suffix on unquoted octal constants * `Z` prefix on unquoted hexadecimal constants (dangerous) |