@@ -13,7 +13,10 @@ pub struct MiriAllocBytes {
13
13
/// Stored layout information about the allocation.
14
14
layout : alloc:: Layout ,
15
15
/// 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`.
17
20
ptr : * mut u8 ,
18
21
}
19
22
@@ -27,8 +30,13 @@ impl Clone for MiriAllocBytes {
27
30
28
31
impl Drop for MiriAllocBytes {
29
32
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
+ } ;
30
38
// 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 ) }
32
40
}
33
41
}
34
42
@@ -51,21 +59,21 @@ impl std::ops::DerefMut for MiriAllocBytes {
51
59
}
52
60
53
61
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()`.
58
65
fn alloc_with (
59
66
size : usize ,
60
67
align : usize ,
61
68
alloc_fn : impl FnOnce ( Layout ) -> * mut u8 ,
62
69
) -> 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 } ;
65
70
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) ;
67
75
if ptr. is_null ( ) {
68
- Err ( layout )
76
+ Err ( alloc_layout )
69
77
} else {
70
78
// SAFETY: All `MiriAllocBytes` invariants are fulfilled.
71
79
Ok ( Self { ptr, layout } )
0 commit comments