Skip to content

Commit 1b374df

Browse files
committed
differentiate between layout and alloc_layout
1 parent 56c363b commit 1b374df

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

src/tools/miri/src/alloc_bytes.rs

+18-10
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ pub struct MiriAllocBytes {
1313
/// Stored layout information about the allocation.
1414
layout: alloc::Layout,
1515
/// Pointer to the allocation contents.
16-
/// Invariant: `self.ptr` points to memory allocated with `self.layout`.
16+
/// Invariant:
17+
/// * If `self.layout.size() == 0`, then `self.ptr` is some suitably aligned pointer
18+
/// that was allocated with the same layout but `size == 1`.
19+
/// * Otherwise, `self.ptr` points to memory allocated with `self.layout`.
1720
ptr: *mut u8,
1821
}
1922

@@ -27,8 +30,13 @@ impl Clone for MiriAllocBytes {
2730

2831
impl Drop for MiriAllocBytes {
2932
fn drop(&mut self) {
33+
let alloc_layout = if self.layout.size() == 0 {
34+
Layout::from_size_align(1, self.layout.align()).unwrap()
35+
} else {
36+
self.layout
37+
};
3038
// SAFETY: Invariant, `self.ptr` points to memory allocated with `self.layout`.
31-
unsafe { alloc::dealloc(self.ptr, self.layout) }
39+
unsafe { alloc::dealloc(self.ptr, alloc_layout) }
3240
}
3341
}
3442

@@ -51,21 +59,21 @@ impl std::ops::DerefMut for MiriAllocBytes {
5159
}
5260

5361
impl MiriAllocBytes {
54-
/// This method factors out how a `MiriAllocBytes` object is allocated,
55-
/// specifically given an allocation function `alloc_fn`.
56-
/// `alloc_fn` is only used with `size != 0`.
57-
/// Returns `Err(layout)` if the allocation function returns a `ptr` where `ptr.is_null()`.
62+
/// This method factors out how a `MiriAllocBytes` object is allocated, given a specific allocation function.
63+
/// If `size == 0` we allocate using a different `alloc_layout` with `size = 1`, to ensure each allocation has a unique address.
64+
/// Returns `Err(alloc_layout)` if the allocation function returns a `ptr` where `ptr.is_null()`.
5865
fn alloc_with(
5966
size: usize,
6067
align: usize,
6168
alloc_fn: impl FnOnce(Layout) -> *mut u8,
6269
) -> Result<MiriAllocBytes, Layout> {
63-
// When size is 0 we allocate 1 byte anyway, so addresses don't possibly overlap.
64-
let size = if size == 0 { 1 } else { size };
6570
let layout = Layout::from_size_align(size, align).unwrap();
66-
let ptr = alloc_fn(layout);
71+
// When size is 0 we allocate 1 byte anyway, to ensure each allocation has a unique address.
72+
let alloc_layout =
73+
if size == 0 { Layout::from_size_align(1, align).unwrap() } else { layout };
74+
let ptr = alloc_fn(alloc_layout);
6775
if ptr.is_null() {
68-
Err(layout)
76+
Err(alloc_layout)
6977
} else {
7078
// SAFETY: All `MiriAllocBytes` invariants are fulfilled.
7179
Ok(Self { ptr, layout })

0 commit comments

Comments
 (0)