Skip to content

Commit 399a92f

Browse files
bors[bot]taiki-e
andauthored
Merge #694
694: epoch: Fix UB in Pointable impl of [MaybeUninit<T>] r=taiki-e a=taiki-e Fixes #693 Co-authored-by: Taiki Endo <te316e89@gmail.com>
2 parents fcec876 + 385bf3e commit 399a92f

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

crossbeam-epoch/src/atomic.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@ impl<T> Pointable for T {
238238
// [`alloc::alloc::Layout::extend`] instead.
239239
#[repr(C)]
240240
struct Array<T> {
241-
size: usize,
241+
/// The number of elements (not the number of bytes).
242+
len: usize,
242243
elements: [MaybeUninit<T>; 0],
243244
}
244245

@@ -247,31 +248,31 @@ impl<T> Pointable for [MaybeUninit<T>] {
247248

248249
type Init = usize;
249250

250-
unsafe fn init(size: Self::Init) -> usize {
251-
let size = mem::size_of::<Array<T>>() + mem::size_of::<MaybeUninit<T>>() * size;
251+
unsafe fn init(len: Self::Init) -> usize {
252+
let size = mem::size_of::<Array<T>>() + mem::size_of::<MaybeUninit<T>>() * len;
252253
let align = mem::align_of::<Array<T>>();
253254
let layout = alloc::Layout::from_size_align(size, align).unwrap();
254255
let ptr = alloc::alloc(layout) as *mut Array<T>;
255256
if ptr.is_null() {
256257
alloc::handle_alloc_error(layout);
257258
}
258-
(*ptr).size = size;
259+
(*ptr).len = len;
259260
ptr as usize
260261
}
261262

262263
unsafe fn deref<'a>(ptr: usize) -> &'a Self {
263264
let array = &*(ptr as *const Array<T>);
264-
slice::from_raw_parts(array.elements.as_ptr() as *const _, array.size)
265+
slice::from_raw_parts(array.elements.as_ptr() as *const _, array.len)
265266
}
266267

267268
unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut Self {
268269
let array = &*(ptr as *mut Array<T>);
269-
slice::from_raw_parts_mut(array.elements.as_ptr() as *mut _, array.size)
270+
slice::from_raw_parts_mut(array.elements.as_ptr() as *mut _, array.len)
270271
}
271272

272273
unsafe fn drop(ptr: usize) {
273274
let array = &*(ptr as *mut Array<T>);
274-
let size = mem::size_of::<Array<T>>() + mem::size_of::<MaybeUninit<T>>() * array.size;
275+
let size = mem::size_of::<Array<T>>() + mem::size_of::<MaybeUninit<T>>() * array.len;
275276
let align = mem::align_of::<Array<T>>();
276277
let layout = alloc::Layout::from_size_align(size, align).unwrap();
277278
alloc::dealloc(ptr as *mut u8, layout);
@@ -1529,7 +1530,8 @@ impl<T: ?Sized + Pointable> Default for Shared<'_, T> {
15291530

15301531
#[cfg(all(test, not(crossbeam_loom)))]
15311532
mod tests {
1532-
use super::Shared;
1533+
use super::{Owned, Shared};
1534+
use std::mem::MaybeUninit;
15331535

15341536
#[test]
15351537
fn valid_tag_i8() {
@@ -1547,4 +1549,11 @@ mod tests {
15471549
use super::Atomic;
15481550
static _U: Atomic<u8> = Atomic::<u8>::null();
15491551
}
1552+
1553+
#[test]
1554+
fn array_init() {
1555+
let owned = Owned::<[MaybeUninit<usize>]>::init(10);
1556+
let arr: &[MaybeUninit<usize>] = &*owned;
1557+
assert_eq!(arr.len(), 10);
1558+
}
15501559
}

0 commit comments

Comments
 (0)