Skip to content

Commit 33e2cfa

Browse files
authored
Merge pull request #86006 from tbkka/tbkka-float-parsing
Fix parsing issues on 32-bit hosts
2 parents 80640f7 + e75a8c0 commit 33e2cfa

File tree

3 files changed

+13
-17
lines changed

3 files changed

+13
-17
lines changed

stdlib/public/core/FloatingPointFromString.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -450,18 +450,18 @@ fileprivate func hexFloat(
450450
) -> ParseResult {
451451
var i = start + 2 // Skip leading '0x'
452452
let firstDigitOffset = i
453-
453+
let limit = UInt64(1) << 60
454454
var significand: UInt64 = 0
455455

456456
//
457457
// Digits before the binary point
458458
//
459459

460460
// Accumulate the most significant 64 bits...
461-
while i < input.count && hexdigit(input[i]) < 16 && significand < (1 << 60) {
462-
significand &<<= 4
463-
significand += UInt64(hexdigit(input[i]))
464-
i += 1
461+
while i < input.count && hexdigit(input[i]) < 16 && significand < limit {
462+
significand &<<= 4
463+
significand += UInt64(hexdigit(input[i]))
464+
i += 1
465465
}
466466

467467
// Initialize binary exponent to the number of bits we collected above
@@ -521,7 +521,7 @@ fileprivate func hexFloat(
521521
}
522522
}
523523
// Pack more bits into the accumulator (up to 60)
524-
while i < input.count && hexdigit(input[i]) < 16 && significand < (1 << 60) {
524+
while i < input.count && hexdigit(input[i]) < 16 && significand < limit {
525525
significand &<<= 4
526526
significand += UInt64(hexdigit(input[i]))
527527
i += 1
@@ -631,12 +631,12 @@ fileprivate func hexFloat(
631631
&& (targetSignificand & 1) == 1)) {
632632
// Round up, test for overflow
633633
targetSignificand += 1
634-
if targetSignificand >= (1 << targetFormat.significandBits) {
634+
if targetSignificand >= (UInt64(1) << targetFormat.significandBits) {
635635
// Normal overflowed, need to renormalize
636636
targetSignificand >>= 1
637637
binaryExponent += 1
638638
} else if (binaryExponent < targetFormat.minBinaryExponent
639-
&& targetSignificand >= (1 << (targetFormat.significandBits - 1))) {
639+
&& targetSignificand >= (UInt64(1) << (targetFormat.significandBits - 1))) {
640640
// Subnormal overflowed to normal
641641
binaryExponent += 1
642642
}
@@ -1769,7 +1769,7 @@ fileprivate func slowDecimalToBinary(
17691769
count: targetFormat.significandBits,
17701770
remainderNonZero: false)
17711771

1772-
if significand >= (1 &<< targetFormat.significandBits) {
1772+
if significand >= (UInt64(1) &<< targetFormat.significandBits) {
17731773
significand >>= 1
17741774
binaryExponent &+= 1
17751775
}
@@ -1865,7 +1865,7 @@ fileprivate func slowDecimalToBinary(
18651865
range: quotientRange,
18661866
count: targetFormat.significandBits,
18671867
remainderNonZero: remainderNonZero)
1868-
if significand >= (1 &<< targetFormat.significandBits) {
1868+
if significand >= (UInt64(1) &<< targetFormat.significandBits) {
18691869
significand >>= 1
18701870
binaryExponent &+= 1
18711871
}
@@ -1889,7 +1889,7 @@ fileprivate func slowDecimalToBinary(
18891889
// exponent. Then we've transitioned from a subnormal to
18901890
// a normal, so the extra overflow bit will naturally get
18911891
// dropped, we just have to bump the exponent.
1892-
if significand >= (1 &<< (targetFormat.significandBits &- 1)) {
1892+
if significand >= (UInt64(1) &<< (targetFormat.significandBits &- 1)) {
18931893
binaryExponent &+= 1
18941894
}
18951895
targetSignificand = significand

test/stdlib/ParseFloat16.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
// Float16 is only available in watchOS 7.0 or newer
88
// UNSUPPORTED: OS=watchos
99

10-
// TODO: Figure out why this test breaks on wasm32
11-
// UNSUPPORTED: CPU=wasm32
12-
1310
// Cannot test with old OS stdlib, because that used libc strtof
1411
// for parsing, which results in incorrect results.
1512
// UNSUPPORTED: use_os_stdlib
@@ -105,7 +102,9 @@ tests.test("NaNs") {
105102
expectRoundTrip(Float16.nan)
106103
expectRoundTrip(-Float16.nan)
107104
expectRoundTrip(Float16(nan:73, signaling:false))
105+
#if !arch(wasm32)
108106
expectRoundTrip(Float16(nan:73, signaling:true))
107+
#endif
109108
expectParse("nan", Float16.nan)
110109
expectParse("NAN", Float16.nan)
111110
expectParse("NaN", Float16.nan)

test/stdlib/ParseFloat64.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55

66
// REQUIRES: executable_test
77

8-
// TODO: Figure out why this test breaks on wasm32
9-
// UNSUPPORTED: CPU=wasm32
10-
118
// Needed to declare the ABI entry point
129
// REQUIRES: swift_feature_Extern
1310

0 commit comments

Comments
 (0)