about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorDaniel Micay <danielmicay@gmail.com>2013-08-06 17:44:40 -0400
committerDaniel Micay <danielmicay@gmail.com>2013-08-06 23:41:20 -0400
commit7d115c94205dd4b937d29c77d1704aa3f801869e (patch)
tree442ecaf695dbb0689805656b178a1c3046468f3b /src/libstd
parentf23fb19ee508515912e136c948a0242cc88a2d4e (diff)
downloadrust-7d115c94205dd4b937d29c77d1704aa3f801869e.tar.gz
rust-7d115c94205dd4b937d29c77d1704aa3f801869e.zip
add an intrinsic for inbounds GEP
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/ptr.rs22
-rw-r--r--src/libstd/unstable/intrinsics.rs11
2 files changed, 32 insertions, 1 deletions
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs
index dfd11f9227d..98fb132672c 100644
--- a/src/libstd/ptr.rs
+++ b/src/libstd/ptr.rs
@@ -272,6 +272,8 @@ pub trait RawPtr<T> {
     fn is_not_null(&self) -> bool;
     unsafe fn to_option(&self) -> Option<&T>;
     fn offset(&self, count: int) -> Self;
+    #[cfg(not(stage0))]
+    unsafe fn offset_inbounds(self, count: int) -> Self;
 }
 
 /// Extension methods for immutable pointers
@@ -304,6 +306,14 @@ impl<T> RawPtr<T> for *T {
     /// Calculates the offset from a pointer.
     #[inline]
     fn offset(&self, count: int) -> *T { offset(*self, count) }
+
+    /// Calculates the offset from a pointer. The offset *must* be in-bounds of
+    /// the object, or one-byte-past-the-end.
+    #[inline]
+    #[cfg(not(stage0))]
+    unsafe fn offset_inbounds(self, count: int) -> *T {
+        intrinsics::offset_inbounds(self, count)
+    }
 }
 
 /// Extension methods for mutable pointers
@@ -336,6 +346,18 @@ impl<T> RawPtr<T> for *mut T {
     /// Calculates the offset from a mutable pointer.
     #[inline]
     fn offset(&self, count: int) -> *mut T { mut_offset(*self, count) }
+
+    /// Calculates the offset from a pointer. The offset *must* be in-bounds of
+    /// the object, or one-byte-past-the-end. An arithmetic overflow is also
+    /// undefined behaviour.
+    ///
+    /// This method should be preferred over `offset` when the guarantee can be
+    /// satisfied, to enable better optimization.
+    #[inline]
+    #[cfg(not(stage0))]
+    unsafe fn offset_inbounds(self, count: int) -> *mut T {
+        intrinsics::offset_inbounds(self as *T, count) as *mut T
+    }
 }
 
 // Equality for pointers
diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs
index 1270a80c354..c60edad3dbd 100644
--- a/src/libstd/unstable/intrinsics.rs
+++ b/src/libstd/unstable/intrinsics.rs
@@ -317,12 +317,21 @@ extern "rust-intrinsic" {
     /// Get the address of the `__morestack` stack growth function.
     pub fn morestack_addr() -> *();
 
-    /// Adjust a pointer by an offset.
+    /// Calculates the offset from a pointer.
     ///
     /// This is implemented as an intrinsic to avoid converting to and from an
     /// integer, since the conversion would throw away aliasing information.
     pub fn offset<T>(dst: *T, offset: int) -> *T;
 
+    /// Calculates the offset from a pointer. The offset *must* be in-bounds of
+    /// the object, or one-byte-past-the-end. An arithmetic overflow is also
+    /// undefined behaviour.
+    ///
+    /// This intrinsic should be preferred over `offset` when the guarantee can
+    /// be satisfied, to enable better optimization.
+    #[cfg(not(stage0))]
+    pub fn offset_inbounds<T>(dst: *T, offset: int) -> *T;
+
     /// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic, with a size of
     /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
     pub fn memcpy32<T>(dst: *mut T, src: *T, count: u32);