@@ -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
2831impl 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
5361impl 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