Skip to content

Commit 695c907

Browse files
committed
Auto merge of #31410 - rkruppe:issue31109, r=pnkfelix
Issue #31109 uncovered two semi-related problems: * A panic in `str::parse::<f64>` * A panic in `rustc::middle::const_eval::lit_to_const` where the result of float parsing was unwrapped. This series of commits fixes both issues and also drive-by-fixes some things I noticed while tracking down the parsing panic.
2 parents 35635ae + a76cb45 commit 695c907

File tree

17 files changed

+119
-41
lines changed

17 files changed

+119
-41
lines changed

src/etc/test-float-parse/_common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::mem::transmute;
1616
#[allow(dead_code)]
1717
pub const SEED: [u32; 3] = [0x243f_6a88, 0x85a3_08d3, 0x1319_8a2e];
1818

19-
pub fn validate(text: String) {
19+
pub fn validate(text: &str) {
2020
let mut out = io::stdout();
2121
let x: f64 = text.parse().unwrap();
2222
let f64_bytes: u64 = unsafe { transmute(x) };

src/etc/test-float-parse/few-ones.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn main() {
2020
for a in &pow {
2121
for b in &pow {
2222
for c in &pow {
23-
validate((a | b | c).to_string());
23+
validate(&(a | b | c).to_string());
2424
}
2525
}
2626
}

src/etc/test-float-parse/huge-pow10.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use _common::validate;
1515
fn main() {
1616
for e in 300..310 {
1717
for i in 0..100000 {
18-
validate(format!("{}e{}", i, e));
18+
validate(&format!("{}e{}", i, e));
1919
}
2020
}
2121
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
mod _common;
12+
13+
use std::char;
14+
use _common::validate;
15+
16+
fn main() {
17+
for n in 0..10 {
18+
let digit = char::from_digit(n, 10).unwrap();
19+
let mut s = "0.".to_string();
20+
for _ in 0..400 {
21+
s.push(digit);
22+
if s.parse::<f64>().is_ok() {
23+
validate(&s);
24+
}
25+
}
26+
}
27+
}

src/etc/test-float-parse/many-digits.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ fn main() {
2323
let mut rnd = IsaacRng::from_seed(&SEED);
2424
let mut range = Range::new(0, 10);
2525
for _ in 0..5_000_000u64 {
26-
let num_digits = rnd.gen_range(100, 300);
26+
let num_digits = rnd.gen_range(100, 400);
2727
let digits = gen_digits(num_digits, &mut range, &mut rnd);
28-
validate(digits);
28+
validate(&digits);
2929
}
3030
}
3131

src/etc/test-float-parse/rand-f64.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ fn main() {
2525
let bits = rnd.next_u64();
2626
let x: f64 = unsafe { transmute(bits) };
2727
if x.is_finite() {
28-
validate(format!("{:e}", x));
28+
validate(&format!("{:e}", x));
2929
i += 1;
3030
}
3131
}

src/etc/test-float-parse/runtests.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@
2121
2222
The actual tests (generating decimal strings and feeding them to dec2flt) is
2323
performed by a set of stand-along rust programs. This script compiles, runs,
24-
and supervises them. In particular, the programs report the strings they
25-
generate and the floating point numbers they converted those strings to.
24+
and supervises them. The programs report the strings they generate and the
25+
floating point numbers they converted those strings to, and this script
26+
checks that the results are correct.
2627
2728
You can run specific tests rather than all of them by giving their names
2829
(without .rs extension) as command line parameters.
@@ -64,9 +65,9 @@
6465
exit code that's not 0, the test fails.
6566
The output on stdout is treated as (f64, f32, decimal) record, encoded thusly:
6667
67-
- The first eight bytes are a binary64 (native endianness).
68-
- The following four bytes are a binary32 (native endianness).
69-
- Then the corresponding string input follows, in ASCII (no newline).
68+
- First, the bits of the f64 encoded as an ASCII hex string.
69+
- Second, the bits of the f32 encoded as an ASCII hex string.
70+
- Then the corresponding string input, in ASCII
7071
- The record is terminated with a newline.
7172
7273
Incomplete records are an error. Not-a-Number bit patterns are invalid too.

src/etc/test-float-parse/short-decimals.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ fn main() {
2222
if i % 10 == 0 {
2323
continue;
2424
}
25-
validate(format!("{}e{}", i, e));
26-
validate(format!("{}e-{}", i, e));
25+
validate(&format!("{}e{}", i, e));
26+
validate(&format!("{}e-{}", i, e));
2727
}
2828
}
2929
}

src/etc/test-float-parse/subnorm.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ use _common::validate;
1616
fn main() {
1717
for bits in 0u32..(1 << 21) {
1818
let single: f32 = unsafe { transmute(bits) };
19-
validate(format!("{:e}", single));
19+
validate(&format!("{:e}", single));
2020
let double: f64 = unsafe { transmute(bits as u64) };
21-
validate(format!("{:e}", double));
21+
validate(&format!("{:e}", double));
2222
}
2323
}

src/etc/test-float-parse/tiny-pow10.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use _common::validate;
1515
fn main() {
1616
for e in 301..327 {
1717
for i in 0..100000 {
18-
validate(format!("{}e-{}", i, e));
18+
validate(&format!("{}e-{}", i, e));
1919
}
2020
}
2121
}

0 commit comments

Comments
 (0)