Skip to content

Commit

Permalink
Check for aliasing in RawViewMut::from_shape_ptr
Browse files Browse the repository at this point in the history
It should deny overlapping indexes. Because it's an unsafe function and
we only do these checks on best-effort basis (caller has to ensure they
are correct), it's a debug assertion.

Removed the small addition to a doc comment that was done in a previous
PR (it was an unfinished idea).

Similar to pr #1410
Finishes and closes #919
  • Loading branch information
bluss committed Aug 3, 2024
1 parent 9873c0a commit b03953a
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 3 deletions.
4 changes: 1 addition & 3 deletions src/dimension/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub fn stride_offset(n: Ix, stride: Ix) -> isize
/// There is overlap if, when iterating through the dimensions in order of
/// increasing stride, the current stride is less than or equal to the maximum
/// possible offset along the preceding axes. (Axes of length ≤1 are ignored.)
pub fn dim_stride_overlap<D: Dimension>(dim: &D, strides: &D) -> bool
pub(crate) fn dim_stride_overlap<D: Dimension>(dim: &D, strides: &D) -> bool
{
let order = strides._fastest_varying_stride_order();
let mut sum_prev_offsets = 0;
Expand Down Expand Up @@ -255,8 +255,6 @@ where D: Dimension
/// allocation. (In other words, the pointer to the first element of the array
/// must be computed using `offset_from_low_addr_ptr_to_logical_ptr` so that
/// negative strides are correctly handled.)
///
/// Note, condition (4) is guaranteed to be checked last
pub(crate) fn can_index_slice<A, D: Dimension>(
data: &[A], dim: &D, strides: &D, mode: CanIndexCheckMode,
) -> Result<(), ShapeError>
Expand Down
2 changes: 2 additions & 0 deletions src/impl_raw_views.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ where D: Dimension
if let Strides::Custom(strides) = &shape.strides {
dimension::strides_non_negative(strides).unwrap();
dimension::max_abs_offset_check_overflow::<A, _>(&dim, strides).unwrap();
assert!(!dimension::dim_stride_overlap(&dim, strides),
"The strides must not allow any element to be referenced by two different indices");
} else {
dimension::size_of_shape_checked(&dim).unwrap();
}
Expand Down
23 changes: 23 additions & 0 deletions tests/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2281,6 +2281,29 @@ fn test_raw_view_mut_from_shape_ptr_deny_neg_strides()
let _view = unsafe { RawArrayViewMut::from_shape_ptr((2, 3).strides((-3isize as usize, 1)), data.as_mut_ptr()) };
}

#[test]
fn test_raw_view_from_shape_allow_overlap()
{
let data = [0, 1, 2];
let view;
unsafe {
let raw_view = RawArrayView::from_shape_ptr((2, 3).strides((0, 1)), data.as_ptr());
view = raw_view.deref_into_view();
}
assert_eq!(view, aview2(&[data, data]));
}

#[should_panic(expected = "strides must not allow any element")]
#[cfg(debug_assertions)]
#[test]
fn test_raw_view_mut_from_shape_deny_overlap()
{
let mut data = [0, 1, 2];
unsafe {
RawArrayViewMut::from_shape_ptr((2, 3).strides((0, 1)), data.as_mut_ptr());
}
}

#[test]
fn test_default()
{
Expand Down

0 comments on commit b03953a

Please sign in to comment.