Skip to content

Commit effa35d

Browse files
authored
[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 #151465.
1 parent aec90f2 commit effa35d

File tree

3 files changed

+21
-6
lines changed

3 files changed

+21
-6
lines changed

flang-rt/lib/runtime/edit-input.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,9 @@ static RT_API_ATTRS ScannedRealInput ScanRealInput(
396396
}
397397
}
398398
} else if (first == radixPointChar || (first >= '0' && first <= '9') ||
399-
(bzMode && (first == ' ' || first == '\t')) || first == 'E' ||
400-
first == 'D' || first == 'Q') {
399+
(bzMode && (first == ' ' || first == '\t')) ||
400+
(remaining.has_value() &&
401+
(first == 'D' || first == 'E' || first == 'Q'))) {
401402
if (first == '0') {
402403
next = io.NextInField(remaining, edit);
403404
if (next && (*next == 'x' || *next == 'X')) { // 0X...
@@ -462,6 +463,14 @@ static RT_API_ATTRS ScannedRealInput ScanRealInput(
462463
// optional exponent letter and the exponent value.
463464
io.SkipSpaces(remaining);
464465
next = io.NextInField(remaining, edit);
466+
if (!next) {
467+
if (remaining.has_value()) {
468+
// bare exponent letter accepted in fixed-width field
469+
hasGoodExponent = true;
470+
} else {
471+
return {}; // error
472+
}
473+
}
465474
}
466475
}
467476
if (next &&

flang-rt/unittests/Runtime/NumericalFormatTest.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,10 @@ TEST(IOApiTests, EditDoubleInputValues) {
965965
{"(RU,E9.1)", " 1.0E-325", 0x1, 0},
966966
{"(E9.1)", "-1.0E-325", 0x8000000000000000, 0},
967967
{"(RD,E9.1)", "-1.0E-325", 0x8000000000000001, 0},
968-
{"(F7.0))", "+NaN(q)", 0x7ff8000000000000, 0},
968+
{"(F7.0)", "+NaN(q)", 0x7ff8000000000000, 0},
969+
{"(G)", "D", 0, IostatBadRealInput},
970+
{"(G0)", "D", 0, IostatErrorInFormat},
971+
{"(G1.0)", "D", 0, 0},
969972
};
970973
for (auto const &[format, data, want, iostat] : testCases) {
971974
auto cookie{IONAME(BeginInternalFormattedInput)(
@@ -988,13 +991,13 @@ TEST(IOApiTests, EditDoubleInputValues) {
988991
// union value
989992
IONAME(GetIoMsg)(cookie, iomsg, bufferSize - 1);
990993
auto status{IONAME(EndIoStatement)(cookie)};
991-
ASSERT_EQ(status, iostat)
994+
EXPECT_EQ(status, iostat)
992995
<< '\'' << format << "' failed reading '" << data << "', status "
993996
<< static_cast<int>(status) << " != expected " << iostat << " iomsg '"
994997
<< iomsg << "'";
995998

996999
// Ensure raw uint64 value matches expected conversion from double
997-
ASSERT_EQ(u.raw, want) << '\'' << format << "' failed reading '" << data
1000+
EXPECT_EQ(u.raw, want) << '\'' << format << "' failed reading '" << data
9981001
<< "', want " << want << ", got " << u.raw;
9991002
}
10001003
}

flang/docs/Extensions.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,9 @@ end
479479
* Old-style `PARAMETER pi=3.14` statement without parentheses
480480
[-falternative-parameter-statement]
481481
* `UNSIGNED` type (-funsigned)
482+
* Default exponent of zero, e.g. `3.14159E`, on a READ from a
483+
fixed-width input field. Includes the case with only an
484+
exponent letter for compatibility with other compilers.
482485

483486
### Extensions and legacy features deliberately not supported
484487

@@ -492,7 +495,7 @@ end
492495
* `VIRTUAL` as synonym for `DIMENSION`
493496
* `ENCODE` and `DECODE` as synonyms for internal I/O
494497
* `IMPLICIT AUTOMATIC`, `IMPLICIT STATIC`
495-
* Default exponent of zero, e.g. `3.14159E`
498+
* Default exponent of zero, e.g. `3.14159E`, on a literal constant
496499
* Characters in defined operators that are neither letters nor digits
497500
* `B` suffix on unquoted octal constants
498501
* `Z` prefix on unquoted hexadecimal constants (dangerous)

0 commit comments

Comments
 (0)