]> git.lizzy.rs Git - rust.git/commitdiff
Add array indexing for-loop test.
authorScott Olson <scott@solson.me>
Mon, 21 Mar 2016 08:37:31 +0000 (02:37 -0600)
committerScott Olson <scott@solson.me>
Mon, 21 Mar 2016 08:37:31 +0000 (02:37 -0600)
src/memory.rs
test/arrays.rs

index 3ac5688c190932a5507a44b6c65a5c28408b3ddc..cd0ee4f687892f81696b837328ec1d2e3ffc41d3 100644 (file)
@@ -100,36 +100,44 @@ fn get_bytes(&self, ptr: Pointer, size: usize) -> EvalResult<&[u8]> {
     }
 
     fn get_bytes_mut(&mut self, ptr: Pointer, size: usize) -> EvalResult<&mut [u8]> {
+        try!(self.clear_relocations(ptr, size));
         let alloc = try!(self.get_mut(ptr.alloc_id));
-        try!(alloc.check_no_relocations(ptr.offset, ptr.offset + size));
         Ok(&mut alloc.bytes[ptr.offset..ptr.offset + size])
     }
 
+    fn clear_relocations(&mut self, ptr: Pointer, size: usize) -> EvalResult<()> {
+        let start = ptr.offset.saturating_sub(self.pointer_size - 1);
+        let end = ptr.offset + size;
+        let alloc = try!(self.get_mut(ptr.alloc_id));
+        let keys: Vec<_> = alloc.relocations
+            .range(Included(&start), Excluded(&end))
+            .map(|(&k, _)| k)
+            .collect();
+        for k in keys {
+            alloc.relocations.remove(&k);
+        }
+        Ok(())
+    }
+
+    fn copy_relocations(&mut self, src: Pointer, dest: Pointer, size: usize) -> EvalResult<()> {
+        let relocations: Vec<_> = try!(self.get_mut(src.alloc_id)).relocations
+            .range(Included(&src.offset), Excluded(&(src.offset + size)))
+            .map(|(&offset, &alloc_id)| {
+                // Update relocation offsets for the new positions in the destination allocation.
+                (offset + dest.offset - src.offset, alloc_id)
+            }).collect();
+        try!(self.get_mut(dest.alloc_id)).relocations.extend(relocations);
+        Ok(())
+    }
+
     pub fn copy(&mut self, src: Pointer, dest: Pointer, size: usize) -> EvalResult<()> {
-        let (src_bytes, mut relocations) = {
+        let src_bytes = {
             let alloc = try!(self.get_mut(src.alloc_id));
             try!(alloc.check_relocation_edges(src.offset, src.offset + size));
-            let bytes = alloc.bytes[src.offset..src.offset + size].as_mut_ptr();
-
-            let relocations: Vec<(usize, AllocId)> = alloc.relocations
-                .range(Included(&src.offset), Excluded(&(src.offset + size)))
-                .map(|(&k, &v)| (k, v))
-                .collect();
-
-            (bytes, relocations)
+            alloc.bytes[src.offset..src.offset + size].as_mut_ptr()
         };
-
-        // Update relocation offsets for the new positions in the destination allocation.
-        for &mut (ref mut offset, _) in &mut relocations {
-            *offset += dest.offset;
-            *offset -= src.offset;
-        }
-
         let dest_bytes = try!(self.get_bytes_mut(dest, size)).as_mut_ptr();
 
-        // TODO(tsion): Clear the destination range's existing relocations.
-        try!(self.get_mut(dest.alloc_id)).relocations.extend(relocations);
-
         // SAFE: The above indexing would have panicked if there weren't at least `size` bytes
         // behind `src` and `dest`. Also, we use the overlapping-safe `ptr::copy` if `src` and
         // `dest` could possibly overlap.
@@ -141,7 +149,7 @@ pub fn copy(&mut self, src: Pointer, dest: Pointer, size: usize) -> EvalResult<(
             }
         }
 
-        Ok(())
+        self.copy_relocations(src, dest, size)
     }
 
     pub fn write_bytes(&mut self, ptr: Pointer, src: &[u8]) -> EvalResult<()> {
@@ -160,7 +168,6 @@ pub fn read_ptr(&self, ptr: Pointer) -> EvalResult<Pointer> {
         }
     }
 
-    // TODO(tsion): Detect invalid writes here and elsewhere.
     pub fn write_ptr(&mut self, dest: Pointer, ptr_val: Pointer) -> EvalResult<()> {
         {
             let size = self.pointer_size;
index 2939acfeaee158f85abd2e9fbaa05c5c8d07144a..cd4c91c220a0e47da760cd555ed2faba2783eddf 100755 (executable)
@@ -27,3 +27,13 @@ fn index() -> i32 {
     let a = [0, 10, 20, 30];
     a[2]
 }
+
+#[miri_run]
+fn index_for_loop() -> usize {
+    let mut sum = 0;
+    let a = [0, 10, 20, 30];
+    for i in 0..a.len() {
+        sum += a[i];
+    }
+    sum
+}