Skip to content

Commit

Permalink
Fix Miri failure with -Zmiri-tag-raw-pointers
Browse files Browse the repository at this point in the history
Before this commit, running `MIRIFLAGS="-Zmiri-tag-raw-pointers" cargo
miri test test_map_axis` caused Miri to report undefined behavior in
the `test_map_axis` test. This commit fixes the underlying issue.
Basically, Miri doesn't like us using a reference to an element to
access other elements. Here's some sample code to illustrate the
issue:

```rust
let a: Vec<i32> = vec![5, 6];
let first_elt: &i32 = &a[0];
let ptr: *const i32 = first_elt as *const i32;
// Okay: the data is contained in the data referenced by `first_elt`.
let a0 = unsafe { &*ptr.offset(0) };
assert_eq!(*a0, 5);
// Not okay: the data is not contained in the data referenced by `first_elt`.
let a1 = unsafe { &*ptr.offset(1) };
assert_eq!(*a1, 6);
```

Before this commit, we were using `self.index_axis(axis,
0).map(|first_elt| ...)` to create views of the lanes, from references
to the first elements in the lanes. Accessing elements within those
views (other than the first element) led to the Miri error, since the
view's pointer was derived from a reference to a single element.

Thanks to @5225225 for reporting the issue. (This commit fixes rust-ndarray#1137.)
  • Loading branch information
jturner314 committed Dec 20, 2021
1 parent 6c8b821 commit 81d8659
Showing 1 changed file with 4 additions and 20 deletions.
24 changes: 4 additions & 20 deletions src/impl_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2699,17 +2699,11 @@ where
A: 'a,
S: Data,
{
let view_len = self.len_of(axis);
let view_stride = self.strides.axis(axis);
if view_len == 0 {
if self.len_of(axis) == 0 {
let new_dim = self.dim.remove_axis(axis);
Array::from_shape_simple_fn(new_dim, move || mapping(ArrayView::from(&[])))
} else {
// use the 0th subview as a map to each 1d array view extended from
// the 0th element.
self.index_axis(axis, 0).map(|first_elt| unsafe {
mapping(ArrayView::new_(first_elt, Ix1(view_len), Ix1(view_stride)))
})
Zip::from(self.lanes(axis)).map_collect(mapping)
}
}

Expand All @@ -2730,21 +2724,11 @@ where
A: 'a,
S: DataMut,
{
let view_len = self.len_of(axis);
let view_stride = self.strides.axis(axis);
if view_len == 0 {
if self.len_of(axis) == 0 {
let new_dim = self.dim.remove_axis(axis);
Array::from_shape_simple_fn(new_dim, move || mapping(ArrayViewMut::from(&mut [])))
} else {
// use the 0th subview as a map to each 1d array view extended from
// the 0th element.
self.index_axis_mut(axis, 0).map_mut(|first_elt| unsafe {
mapping(ArrayViewMut::new_(
first_elt,
Ix1(view_len),
Ix1(view_stride),
))
})
Zip::from(self.lanes_mut(axis)).map_collect(mapping)
}
}

Expand Down

0 comments on commit 81d8659

Please sign in to comment.