@@ -13,10 +13,7 @@ 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:
17
- /// * If `self.layout.size() == 0`, then `self.ptr` is some suitably aligned pointer
18
- /// without provenance (and no actual memory was allocated).
19
- /// * Otherwise, `self.ptr` points to memory allocated with `self.layout`.
16
+ /// Invariant: `self.ptr` points to memory allocated with `self.layout`.
20
17
ptr : * mut u8 ,
21
18
}
22
19
@@ -30,10 +27,8 @@ impl Clone for MiriAllocBytes {
30
27
31
28
impl Drop for MiriAllocBytes {
32
29
fn drop ( & mut self ) {
33
- if self . layout . size ( ) != 0 {
34
- // SAFETY: Invariant, `self.ptr` points to memory allocated with `self.layout`.
35
- unsafe { alloc:: dealloc ( self . ptr , self . layout ) }
36
- }
30
+ // SAFETY: Invariant, `self.ptr` points to memory allocated with `self.layout`.
31
+ unsafe { alloc:: dealloc ( self . ptr , self . layout ) }
37
32
}
38
33
}
39
34
@@ -58,25 +53,23 @@ impl std::ops::DerefMut for MiriAllocBytes {
58
53
impl MiriAllocBytes {
59
54
/// This method factors out how a `MiriAllocBytes` object is allocated,
60
55
/// specifically given an allocation function `alloc_fn`.
61
- /// `alloc_fn` is only used if `size != 0`.
62
- /// Returns `Err(layout)` if the allocation function returns a `ptr` that is `ptr.is_null()`.
56
+ /// `alloc_fn` is only used with `size != 0`.
57
+ /// Returns `Err(layout)` if the allocation function returns a `ptr` where `ptr.is_null()`.
63
58
fn alloc_with (
64
59
size : usize ,
65
60
align : usize ,
66
61
alloc_fn : impl FnOnce ( Layout ) -> * mut u8 ,
67
62
) -> 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 } ;
68
65
let layout = Layout :: from_size_align ( size, align) . unwrap ( ) ;
69
- let ptr = if size == 0 {
70
- std:: ptr:: without_provenance_mut ( align)
66
+ let ptr = alloc_fn ( layout) ;
67
+ if ptr. is_null ( ) {
68
+ Err ( layout)
71
69
} else {
72
- let ptr = alloc_fn ( layout) ;
73
- if ptr. is_null ( ) {
74
- return Err ( layout) ;
75
- }
76
- ptr
77
- } ;
78
- // SAFETY: All `MiriAllocBytes` invariants are fulfilled.
79
- Ok ( Self { ptr, layout } )
70
+ // SAFETY: All `MiriAllocBytes` invariants are fulfilled.
71
+ Ok ( Self { ptr, layout } )
72
+ }
80
73
}
81
74
}
82
75
@@ -85,7 +78,7 @@ impl AllocBytes for MiriAllocBytes {
85
78
let slice = slice. into ( ) ;
86
79
let size = slice. len ( ) ;
87
80
let align = align. bytes_usize ( ) ;
88
- // SAFETY: `alloc_fn` will only be used if `size != 0`.
81
+ // SAFETY: `alloc_fn` will only be used with `size != 0`.
89
82
let alloc_fn = |layout| unsafe { alloc:: alloc ( layout) } ;
90
83
let alloc_bytes = MiriAllocBytes :: alloc_with ( size, align, alloc_fn)
91
84
. unwrap_or_else ( |layout| alloc:: handle_alloc_error ( layout) ) ;
@@ -98,7 +91,7 @@ impl AllocBytes for MiriAllocBytes {
98
91
fn zeroed ( size : Size , align : Align ) -> Option < Self > {
99
92
let size = size. bytes_usize ( ) ;
100
93
let align = align. bytes_usize ( ) ;
101
- // SAFETY: `alloc_fn` will only be used if `size != 0`.
94
+ // SAFETY: `alloc_fn` will only be used with `size != 0`.
102
95
let alloc_fn = |layout| unsafe { alloc:: alloc_zeroed ( layout) } ;
103
96
MiriAllocBytes :: alloc_with ( size, align, alloc_fn) . ok ( )
104
97
}
0 commit comments