librustc: Don't create &[T] slices with NULL as the ptr.
This commit is contained in:
parent
e646188f66
commit
31570cb22e
@ -27,6 +27,10 @@
|
||||
use slice::{MutableOrdVector, MutableVectorAllocating, CloneableVector};
|
||||
use slice::{Items, MutItems};
|
||||
|
||||
|
||||
#[doc(hidden)]
|
||||
pub static PTR_MARKER: u8 = 0;
|
||||
|
||||
/// An owned, growable vector.
|
||||
///
|
||||
/// # Examples
|
||||
@ -71,7 +75,13 @@ impl<T> Vec<T> {
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn new() -> Vec<T> {
|
||||
Vec { len: 0, cap: 0, ptr: 0 as *mut T }
|
||||
// If we have a 0-sized vector, then the base pointer should not be NULL
|
||||
// because an iterator over the slice will attempt to yield the base
|
||||
// pointer as the first element in the vector, but this will end up
|
||||
// being Some(NULL) which is optimized to None. So instead we set ptr
|
||||
// to some arbitrary non-null value which is fine since we never call
|
||||
// deallocate on the ptr if cap is 0.
|
||||
Vec { len: 0, cap: 0, ptr: &PTR_MARKER as *const _ as *mut T }
|
||||
}
|
||||
|
||||
/// Constructs a new, empty `Vec` with the specified capacity.
|
||||
@ -88,7 +98,7 @@ pub fn new() -> Vec<T> {
|
||||
#[inline]
|
||||
pub fn with_capacity(capacity: uint) -> Vec<T> {
|
||||
if mem::size_of::<T>() == 0 {
|
||||
Vec { len: 0, cap: uint::MAX, ptr: 0 as *mut T }
|
||||
Vec { len: 0, cap: uint::MAX, ptr: &PTR_MARKER as *const _ as *mut T }
|
||||
} else if capacity == 0 {
|
||||
Vec::new()
|
||||
} else {
|
||||
@ -1206,15 +1216,7 @@ pub fn init<'a>(&'a self) -> &'a [T] {
|
||||
/// would also make any pointers to it invalid.
|
||||
#[inline]
|
||||
pub fn as_ptr(&self) -> *const T {
|
||||
// If we have a 0-sized vector, then the base pointer should not be NULL
|
||||
// because an iterator over the slice will attempt to yield the base
|
||||
// pointer as the first element in the vector, but this will end up
|
||||
// being Some(NULL) which is optimized to None.
|
||||
if mem::size_of::<T>() == 0 {
|
||||
1 as *const T
|
||||
} else {
|
||||
self.ptr as *const T
|
||||
}
|
||||
self.ptr as *const T
|
||||
}
|
||||
|
||||
/// Returns a mutable unsafe pointer to the vector's buffer.
|
||||
@ -1226,12 +1228,7 @@ pub fn as_ptr(&self) -> *const T {
|
||||
/// would also make any pointers to it invalid.
|
||||
#[inline]
|
||||
pub fn as_mut_ptr(&mut self) -> *mut T {
|
||||
// see above for the 0-size check
|
||||
if mem::size_of::<T>() == 0 {
|
||||
1 as *mut T
|
||||
} else {
|
||||
self.ptr
|
||||
}
|
||||
self.ptr
|
||||
}
|
||||
|
||||
/// Retains only the elements specified by the predicate.
|
||||
|
@ -155,8 +155,9 @@ pub fn trans_slice_vstore<'a>(
|
||||
let llcount = C_uint(ccx, count);
|
||||
let llfixed;
|
||||
if count == 0 {
|
||||
// Zero-length array: just use NULL as the data pointer
|
||||
llfixed = C_null(vt.llunit_ty.ptr_to());
|
||||
// Just create a zero-sized alloca to preserve
|
||||
// the non-null invariant of the inner slice ptr
|
||||
llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
|
||||
} else {
|
||||
// Make a fixed-length backing array and allocate it on the stack.
|
||||
llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
|
||||
|
Loading…
Reference in New Issue
Block a user