Skip to content

Commit 20a256a

Browse files
committed
Avoid latent (harmless) overflow in core::slice.
This overflow does not cause any problems; it just causes errors to be signalled when compiling with `-C debug-assertions`. Fix rust-lang#24997
1 parent f9ecc6e commit 20a256a

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

src/libcore/slice.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ fn size_from_ptr<T>(_: *const T) -> usize {
632632

633633

634634
// Use macro to be generic over const/mut
635-
macro_rules! slice_offset {
635+
macro_rules! slice_add_offset {
636636
($ptr:expr, $by:expr) => {{
637637
let ptr = $ptr;
638638
if size_from_ptr(ptr) == 0 {
@@ -643,6 +643,17 @@ macro_rules! slice_offset {
643643
}};
644644
}
645645

646+
macro_rules! slice_sub_offset {
647+
($ptr:expr, $by:expr) => {{
648+
let ptr = $ptr;
649+
if size_from_ptr(ptr) == 0 {
650+
transmute(ptr as usize - $by)
651+
} else {
652+
ptr.offset(-$by)
653+
}
654+
}};
655+
}
656+
646657
macro_rules! slice_ref {
647658
($ptr:expr) => {{
648659
let ptr = $ptr;
@@ -672,7 +683,7 @@ macro_rules! iterator {
672683
None
673684
} else {
674685
let old = self.ptr;
675-
self.ptr = slice_offset!(self.ptr, 1);
686+
self.ptr = slice_add_offset!(self.ptr, 1);
676687
Some(slice_ref!(old))
677688
}
678689
}
@@ -714,7 +725,7 @@ macro_rules! iterator {
714725
if self.end == self.ptr {
715726
None
716727
} else {
717-
self.end = slice_offset!(self.end, -1);
728+
self.end = slice_sub_offset!(self.end, 1);
718729
Some(slice_ref!(self.end))
719730
}
720731
}
@@ -816,7 +827,7 @@ impl<'a, T> Iter<'a, T> {
816827
fn iter_nth(&mut self, n: usize) -> Option<&'a T> {
817828
match self.as_slice().get(n) {
818829
Some(elem_ref) => unsafe {
819-
self.ptr = slice_offset!(elem_ref as *const _, 1);
830+
self.ptr = slice_add_offset!(elem_ref as *const _, 1);
820831
Some(slice_ref!(elem_ref))
821832
},
822833
None => {
@@ -959,7 +970,7 @@ impl<'a, T> IterMut<'a, T> {
959970
fn iter_nth(&mut self, n: usize) -> Option<&'a mut T> {
960971
match make_mut_slice!(T => &'a mut [T]: self.ptr, self.end).get_mut(n) {
961972
Some(elem_ref) => unsafe {
962-
self.ptr = slice_offset!(elem_ref as *mut _, 1);
973+
self.ptr = slice_add_offset!(elem_ref as *mut _, 1);
963974
Some(slice_ref!(elem_ref))
964975
},
965976
None => {

0 commit comments

Comments
 (0)