Skip to content

core: Apply stability attributes to ptr mod #14529

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 5, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/doc/guide-unsafe.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,14 +213,14 @@ pub struct Unique<T> {
impl<T: Send> Unique<T> {
pub fn new(value: T) -> Unique<T> {
unsafe {
let ptr = malloc(std::mem::size_of::<T>() as size_t) as *mut T;
let ptr = malloc(mem::size_of::<T>() as size_t) as *mut T;
// we *need* valid pointer.
assert!(!ptr.is_null());
// `*ptr` is uninitialized, and `*ptr = value` would
// attempt to destroy it `overwrite` moves a value into
// this memory without attempting to drop the original
// value.
mem::overwrite(&mut *ptr, value);
ptr::write(&mut *ptr, value);
Unique{ptr: ptr}
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/libarena/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use std::intrinsics::{TyDesc, get_tydesc};
use std::intrinsics;
use std::mem;
use std::num;
use std::ptr::read;
use std::ptr;
use std::rc::Rc;
use std::rt::heap::allocate;

Expand Down Expand Up @@ -209,7 +209,7 @@ impl Arena {
let ptr = self.alloc_copy_inner(mem::size_of::<T>(),
mem::min_align_of::<T>());
let ptr = ptr as *mut T;
mem::overwrite(&mut (*ptr), op());
ptr::write(&mut (*ptr), op());
return &*ptr;
}
}
Expand Down Expand Up @@ -262,7 +262,7 @@ impl Arena {
// has *not* been initialized yet.
*ty_ptr = mem::transmute(tydesc);
// Actually initialize it
mem::overwrite(&mut(*ptr), op());
ptr::write(&mut(*ptr), op());
// Now that we are done, update the tydesc to indicate that
// the object is there.
*ty_ptr = bitpack_tydesc_ptr(tydesc, true);
Expand Down Expand Up @@ -360,7 +360,7 @@ impl<T> TypedArenaChunk<T> {
let mut chunk = unsafe {
let chunk = allocate(size, mem::min_align_of::<TypedArenaChunk<T>>());
let mut chunk: Box<TypedArenaChunk<T>> = mem::transmute(chunk);
mem::overwrite(&mut chunk.next, next);
ptr::write(&mut chunk.next, next);
chunk
};

Expand All @@ -376,7 +376,7 @@ impl<T> TypedArenaChunk<T> {
if intrinsics::needs_drop::<T>() {
let mut start = self.start();
for _ in range(0, len) {
read(start as *T); // run the destructor on the pointer
ptr::read(start as *T); // run the destructor on the pointer
start = start.offset(mem::size_of::<T>() as int)
}
}
Expand Down Expand Up @@ -442,7 +442,7 @@ impl<T> TypedArena<T> {
}

let ptr: &'a mut T = mem::transmute(this.ptr);
mem::overwrite(ptr, object);
ptr::write(ptr, object);
this.ptr = this.ptr.offset(1);
let ptr: &'a T = ptr;
ptr
Expand Down
11 changes: 6 additions & 5 deletions src/libcollections/priority_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
#![allow(missing_doc)]

use std::clone::Clone;
use std::mem::{overwrite, zeroed, replace, swap};
use std::mem::{zeroed, replace, swap};
use std::ptr;
use std::slice;

/// A priority queue implemented with a binary heap
Expand Down Expand Up @@ -163,13 +164,13 @@ impl<T: Ord> PriorityQueue<T> {
let parent = (pos - 1) >> 1;
if new > *self.data.get(parent) {
let x = replace(self.data.get_mut(parent), zeroed());
overwrite(self.data.get_mut(pos), x);
ptr::write(self.data.get_mut(pos), x);
pos = parent;
continue
}
break
}
overwrite(self.data.get_mut(pos), new);
ptr::write(self.data.get_mut(pos), new);
}
}

Expand All @@ -185,12 +186,12 @@ impl<T: Ord> PriorityQueue<T> {
child = right;
}
let x = replace(self.data.get_mut(child), zeroed());
overwrite(self.data.get_mut(pos), x);
ptr::write(self.data.get_mut(pos), x);
pos = child;
child = 2 * pos + 1;
}

overwrite(self.data.get_mut(pos), new);
ptr::write(self.data.get_mut(pos), new);
self.siftup(start, pos);
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/libcore/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,16 +155,16 @@ pub unsafe fn uninit<T>() -> T {
/// contained at the location `dst`. This could leak allocations or resources,
/// so care must be taken to previously deallocate the value at `dst`.
#[inline]
#[stable]
#[deprecated = "use ptr::write"]
pub unsafe fn overwrite<T>(dst: *mut T, src: T) {
intrinsics::move_val_init(&mut *dst, src)
}

/// Deprecated, use `overwrite` instead
#[inline]
#[deprecated = "this function has been renamed to `overwrite`"]
#[deprecated = "use ptr::write"]
pub unsafe fn move_val_init<T>(dst: &mut T, src: T) {
overwrite(dst, src)
ptr::write(dst, src)
}

/// Convert an u16 to little endian from the target's endianness.
Expand Down
90 changes: 60 additions & 30 deletions src/libcore/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,36 +95,6 @@ use option::{Some, None, Option};

#[cfg(not(test))] use cmp::{PartialEq, Eq, PartialOrd, Equiv};

/// Return the offset of the first null pointer in `buf`.
#[inline]
pub unsafe fn buf_len<T>(buf: **T) -> uint {
position(buf, |i| *i == null())
}

impl<T> Clone for *T {
#[inline]
fn clone(&self) -> *T {
*self
}
}

impl<T> Clone for *mut T {
#[inline]
fn clone(&self) -> *mut T {
*self
}
}

/// Return the first offset `i` such that `f(buf[i]) == true`.
#[inline]
pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
let mut i = 0;
loop {
if f(&(*buf.offset(i as int))) { return i; }
else { i += 1; }
}
}

/// Create a null pointer.
///
/// # Example
Expand All @@ -136,6 +106,7 @@ pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
/// assert!(p.is_null());
/// ```
#[inline]
#[unstable = "may need a different name after pending changes to pointer types"]
pub fn null<T>() -> *T { 0 as *T }

/// Create an unsafe mutable null pointer.
Expand All @@ -149,6 +120,7 @@ pub fn null<T>() -> *T { 0 as *T }
/// assert!(p.is_null());
/// ```
#[inline]
#[unstable = "may need a different name after pending changes to pointer types"]
pub fn mut_null<T>() -> *mut T { 0 as *mut T }

/// Copies data from one location to another.
Expand All @@ -174,6 +146,7 @@ pub fn mut_null<T>() -> *mut T { 0 as *mut T }
/// ```
///
#[inline]
#[unstable]
pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
intrinsics::copy_memory(dst, src, count)
}
Expand Down Expand Up @@ -215,6 +188,7 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
/// If the source and destination overlap then the behavior of this
/// function is undefined.
#[inline]
#[unstable]
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
src: *T,
count: uint) {
Expand All @@ -224,19 +198,23 @@ pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
/// bytes of memory starting at `dst` to `c`.
#[inline]
#[experimental = "uncertain about naming and semantics"]
pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
intrinsics::set_memory(dst, c, count)
}

/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
#[inline]
#[experimental = "uncertain about naming and semantics"]
#[allow(experimental)]
pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
set_memory(dst, 0, count);
}

/// Swap the values at two mutable locations of the same type, without
/// deinitialising either. They may overlap.
#[inline]
#[unstable]
pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
// Give ourselves some scratch space to work with
let mut tmp: T = mem::uninitialized();
Expand All @@ -255,13 +233,15 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
/// Replace the value at a mutable location with a new one, returning the old
/// value, without deinitialising either.
#[inline]
#[unstable]
pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
mem::swap(mem::transmute(dest), &mut src); // cannot overlap
src
}

/// Reads the value from `*src` and returns it.
#[inline(always)]
#[unstable]
pub unsafe fn read<T>(src: *T) -> T {
let mut tmp: T = mem::uninitialized();
copy_nonoverlapping_memory(&mut tmp, src, 1);
Expand All @@ -271,6 +251,8 @@ pub unsafe fn read<T>(src: *T) -> T {
/// Reads the value from `*src` and nulls it out.
/// This currently prevents destructors from executing.
#[inline(always)]
#[experimental]
#[allow(experimental)]
pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
// Copy the data out from `dest`:
let tmp = read(&*dest);
Expand All @@ -281,9 +263,22 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
tmp
}

/// Unsafely overwrite a memory location with the given value without destroying
/// the old value.
///
/// This operation is unsafe because it does not destroy the previous value
/// contained at the location `dst`. This could leak allocations or resources,
/// so care must be taken to previously deallocate the value at `dst`.
#[inline]
#[unstable]
pub unsafe fn write<T>(dst: *mut T, src: T) {
intrinsics::move_val_init(&mut *dst, src)
}

/// Given a **T (pointer to an array of pointers),
/// iterate through each *T, up to the provided `len`,
/// passing to the provided callback function
#[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
if arr.is_null() {
fail!("ptr::array_each_with_len failure: arr input is null pointer");
Expand All @@ -303,6 +298,8 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
///
/// This will only work with a null-terminated
/// pointer array.
#[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
#[allow(deprecated)]
pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
if arr.is_null() {
fail!("ptr::array_each_with_len failure: arr input is null pointer");
Expand All @@ -311,6 +308,25 @@ pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
array_each_with_len(arr, len, cb);
}

/// Return the offset of the first null pointer in `buf`.
#[inline]
#[deprecated = "use a loop and RawPtr::offset"]
#[allow(deprecated)]
pub unsafe fn buf_len<T>(buf: **T) -> uint {
position(buf, |i| *i == null())
}

/// Return the first offset `i` such that `f(buf[i]) == true`.
#[inline]
#[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
let mut i = 0;
loop {
if f(&(*buf.offset(i as int))) { return i; }
else { i += 1; }
}
}

/// Methods on raw pointers
pub trait RawPtr<T> {
/// Returns the null pointer.
Expand Down Expand Up @@ -426,6 +442,20 @@ impl<T> Equiv<*T> for *mut T {
}
}

impl<T> Clone for *T {
#[inline]
fn clone(&self) -> *T {
*self
}
}

impl<T> Clone for *mut T {
#[inline]
fn clone(&self) -> *mut T {
*self
}
}

// Equality for extern "C" fn pointers
#[cfg(not(test))]
mod externfnpointers {
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/should_not_exist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl<A: Clone> Clone for ~[A] {
try_finally(
&mut i, (),
|i, ()| while *i < len {
mem::overwrite(
ptr::write(
&mut(*p.offset(*i as int)),
self.unsafe_ref(*i).clone());
*i += 1;
Expand Down
3 changes: 2 additions & 1 deletion src/libcore/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1093,7 +1093,7 @@ impl<'a,T> MutableVector<'a, T> for &'a mut [T] {

#[inline]
unsafe fn init_elem(self, i: uint, val: T) {
mem::overwrite(&mut (*self.as_mut_ptr().offset(i as int)), val);
ptr::write(&mut (*self.as_mut_ptr().offset(i as int)), val);
}

#[inline]
Expand Down Expand Up @@ -1218,6 +1218,7 @@ pub mod bytes {

impl<'a> MutableByteVector for &'a mut [u8] {
#[inline]
#[allow(experimental)]
fn set_memory(self, value: u8) {
unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) };
}
Expand Down