-
-
Notifications
You must be signed in to change notification settings - Fork 483
Description
The following program fails to run in Miri with an unaligned memory access:
use rand::Rng;
fn main()
{
let mut rng = rand::thread_rng();
let _val = rng.gen::<i32>();
let _val = rng.gen::<usize>(); // causes unaligned memory access
}This is caused by this line of code:
Line 186 in 852988b
| unsafe { *(&results[index] as *const u32 as *const u64) } |
That casts a 4-aligned pointer to a *const i64 and then uses that for a read. i64 reads must be 8-aligned. There is a comment in the souce indicating that this "requires little-endian CPU supporting unaligned reads", but that is not sufficient: the alignment requirement is made by LLVM, not by the CPU. In Rust, all accesses must be aligned on all platforms, no matter what the CPU says; any unaligned access causes UB (on all platforms). Unaligned accesses are only allowed with read_unaligned and write_unaligned.
There is another problem with this code as well: It violates pointer provenance rules. &results[index] as *const u32 creates a raw pointer that may be used to access this particular element, but it is not legal to use this pointer to access neighboring elements that were never cast to a raw pointer. You could try to fix this with something like &results[index..index+1] as *const [u32] as *const u32 as *const u64.
Is the performance of the "fallback code path" really so much worse that all these hacks are worth it?

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.
