From 6d5694a0218c4b7c655425581d0bded79de9067a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 30 Jul 2018 14:00:12 +0200 Subject: [PATCH] fix memrchr in miri --- src/libcore/slice/memchr.rs | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/libcore/slice/memchr.rs b/src/libcore/slice/memchr.rs index 72e7b57a6cb3c..c9d3c7fea9839 100644 --- a/src/libcore/slice/memchr.rs +++ b/src/libcore/slice/memchr.rs @@ -100,24 +100,30 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option { // - the first remaining bytes, < 2 word size let len = text.len(); let ptr = text.as_ptr(); - let usize_bytes = mem::size_of::(); + type Chunk = usize; - let mut offset = { - // We call this just to obtain the length of the suffix - let (_, _, suffix) = unsafe { text.align_to::() }; - len - suffix.len() + let (min_aligned_offset, max_aligned_offset) = { + // We call this just to obtain the length of the prefix and suffix. + // In the middle we always process two chunks at once. + let (prefix, _, suffix) = unsafe { text.align_to::<(Chunk, Chunk)>() }; + (prefix.len(), len - suffix.len()) }; + + let mut offset = max_aligned_offset; if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) { return Some(offset + index); } - // search the body of the text + // search the body of the text, make sure we don't cross min_aligned_offset. + // offset is always aligned, so just testing `>` is sufficient and avoids possible + // overflow. let repeated_x = repeat_byte(x); + let chunk_bytes = mem::size_of::(); - while offset >= 2 * usize_bytes { + while offset > min_aligned_offset { unsafe { - let u = *(ptr.offset(offset as isize - 2 * usize_bytes as isize) as *const usize); - let v = *(ptr.offset(offset as isize - usize_bytes as isize) as *const usize); + let u = *(ptr.offset(offset as isize - 2 * chunk_bytes as isize) as *const Chunk); + let v = *(ptr.offset(offset as isize - chunk_bytes as isize) as *const Chunk); // break if there is a matching byte let zu = contains_zero_byte(u ^ repeated_x); @@ -126,7 +132,7 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option { break; } } - offset -= 2 * usize_bytes; + offset -= 2 * chunk_bytes; } // find the byte before the point the body loop stopped