aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Klausler <pklausler@nvidia.com>2025-08-05 13:39:33 -0700
committerGitHub <noreply@github.com>2025-08-05 13:39:33 -0700
commiteffa35d240f34bcd07f0653b6fbdd999a5dbf02e (patch)
tree1fab4cce061fc7b8f5194eb12b8275ac338d376d
parentaec90f2f27317dbb075a5a816e11b4892f035680 (diff)
downloadllvm-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.cpp13
-rw-r--r--flang-rt/unittests/Runtime/NumericalFormatTest.cpp9
-rw-r--r--flang/docs/Extensions.md5
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)