Skip to content

Commit ff88062

Browse files
authored
Merge pull request #692 from RalfJung/rand
Fix 0-sized getrandom and thread_rng()
2 parents f6fef3b + a50512f commit ff88062

File tree

7 files changed

+48
-20
lines changed

7 files changed

+48
-20
lines changed

src/fn_call.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,11 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
241241
// neither of which have any effect on our current PRNG
242242
let _flags = this.read_scalar(args[3])?.to_i32()?;
243243

244-
let data = gen_random(this, len as usize)?;
245-
this.memory_mut().get_mut(ptr.alloc_id)?
246-
.write_bytes(tcx, ptr, &data)?;
244+
if len > 0 {
245+
let data = gen_random(this, len as usize)?;
246+
this.memory_mut().get_mut(ptr.alloc_id)?
247+
.write_bytes(tcx, ptr, &data)?;
248+
}
247249

248250
this.write_scalar(Scalar::from_uint(len, dest.layout.size), dest)?;
249251
}
@@ -622,6 +624,11 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
622624
this.write_null(dest)?;
623625
}
624626

627+
// We don't support fork so we don't have to do anything for atfork.
628+
"pthread_atfork" => {
629+
this.write_null(dest)?;
630+
}
631+
625632
"mmap" => {
626633
// This is a horrible hack, but since the guard page mechanism calls mmap and expects a particular return value, we just give it that value.
627634
let addr = this.read_scalar(args[0])?.not_undef()?;
@@ -767,11 +774,13 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
767774
// The actual name of 'RtlGenRandom'
768775
"SystemFunction036" => {
769776
let ptr = this.read_scalar(args[0])?.to_ptr()?;
770-
let len = this.read_scalar(args[1])?.to_usize(this)?;
777+
let len = this.read_scalar(args[1])?.to_u32()?;
771778

772-
let data = gen_random(this, len as usize)?;
773-
this.memory_mut().get_mut(ptr.alloc_id)?
774-
.write_bytes(tcx, ptr, &data)?;
779+
if len > 0 {
780+
let data = gen_random(this, len as usize)?;
781+
this.memory_mut().get_mut(ptr.alloc_id)?
782+
.write_bytes(tcx, ptr, &data)?;
783+
}
775784

776785
this.write_scalar(Scalar::from_bool(true), dest)?;
777786
}

test-cargo-miri/run-test.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def test_cargo_miri_run():
4343
)
4444

4545
def test_cargo_miri_test():
46-
test("cargo miri test", ["cargo", "miri", "test", "-q"], "test.stdout.ref", "test.stderr.ref")
46+
test("cargo miri test", ["cargo", "miri", "test", "-q", "--", "-Zmiri-seed=feed"], "test.stdout.ref", "test.stderr.ref")
4747
test("cargo miri test (with filter)",
4848
["cargo", "miri", "test", "-q", "--", "--", "impl"],
4949
"test.stdout.ref2", "test.stderr.ref"

test-cargo-miri/test.stdout.ref

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ test test::rng ... ok
55
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
66

77

8-
running 2 tests
9-
test rng ... ok
8+
running 3 tests
9+
test entropy_rng ... ok
10+
test fixed_rng ... ok
1011
test simple ... ok
1112

12-
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
13+
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
1314

test-cargo-miri/test.stdout.ref2

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out
77
running 1 test
88
test simple ... ok
99

10-
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out
10+
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out
1111

test-cargo-miri/tests/test.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
#![allow(unused_imports)] // FIXME for macOS
2+
13
extern crate rand;
24

3-
use rand::{Rng, SeedableRng};
5+
use rand::{SeedableRng, FromEntropy, Rng, rngs::SmallRng};
46

57
#[test]
68
fn simple() {
@@ -10,13 +12,28 @@ fn simple() {
1012
// Having more than 1 test does seem to make a difference
1113
// (i.e., this calls ptr::swap which having just one test does not).
1214
#[test]
13-
fn rng() {
15+
fn fixed_rng() {
1416
let mut rng = rand::rngs::StdRng::seed_from_u64(0xdeadcafe);
1517
let x: u32 = rng.gen();
1618
let y: u32 = rng.gen();
1719
assert_ne!(x, y);
1820
}
1921

22+
#[test]
23+
fn entropy_rng() {
24+
#[cfg(not(target_os="macos"))] // FIXME entropy does not work on macOS
25+
// (Not disabling the entire test as that would change the output.)
26+
{
27+
// Use this opportunity to test querying the RNG (needs an external crate, hence tested here and not in the compiletest suite)
28+
let mut rng = SmallRng::from_entropy();
29+
let _val = rng.gen::<i32>();
30+
31+
// Also try per-thread RNG.
32+
let mut rng = rand::thread_rng();
33+
let _val = rng.gen::<i32>();
34+
}
35+
}
36+
2037
// A test that won't work on miri
2138
#[cfg(not(miri))]
2239
#[test]

tests/compile-fail/getrandom.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// ignore-macos
2-
// ignore-windows
1+
// ignore-macos: Uses Linux-only APIs
2+
// ignore-windows: Uses Linux-only APIs
33

44
#![feature(rustc_private)]
55
extern crate libc;

tests/run-pass/hashmap.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,13 @@ fn test_map<S: BuildHasher>(mut map: HashMap<i32, i32, S>) {
2727
}
2828

2929
fn main() {
30-
// TODO: Implement random number generation on OS X
3130
if cfg!(not(target_os = "macos")) {
32-
let map_normal: HashMap<i32, i32> = HashMap::new();
33-
test_map(map_normal);
31+
let map: HashMap<i32, i32> = HashMap::default();
32+
test_map(map);
3433
} else {
35-
let map : HashMap<i32, i32, BuildHasherDefault<collections::hash_map::DefaultHasher>> = Default::default();
34+
// TODO: Implement random number generation on OS X.
35+
// Until then, use a deterministic map.
36+
let map : HashMap<i32, i32, BuildHasherDefault<collections::hash_map::DefaultHasher>> = HashMap::default();
3637
test_map(map);
3738
}
3839
}

0 commit comments

Comments
 (0)