interpret: do no ICE on OOB shuffle/insert/extract indices
This commit is contained in:
parent
8e0dd993d6
commit
134e2b2056
@ -379,10 +379,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
let (input, input_len) = self.operand_to_simd(&args[0])?;
|
||||
let (dest, dest_len) = self.place_to_simd(dest)?;
|
||||
assert_eq!(input_len, dest_len, "Return vector length must match input length");
|
||||
assert!(
|
||||
index < dest_len,
|
||||
"Index `{index}` must be in bounds of vector with length {dest_len}"
|
||||
);
|
||||
// Bounds are not checked by typeck so we have to do it ourselves.
|
||||
if index >= input_len {
|
||||
throw_ub_format!(
|
||||
"`simd_insert` index {index} is out-of-bounds of vector with length {input_len}"
|
||||
);
|
||||
}
|
||||
|
||||
for i in 0..dest_len {
|
||||
let place = self.project_index(&dest, i)?;
|
||||
@ -397,10 +399,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
sym::simd_extract => {
|
||||
let index = u64::from(self.read_scalar(&args[1])?.to_u32()?);
|
||||
let (input, input_len) = self.operand_to_simd(&args[0])?;
|
||||
assert!(
|
||||
index < input_len,
|
||||
"index `{index}` must be in bounds of vector with length {input_len}"
|
||||
);
|
||||
// Bounds are not checked by typeck so we have to do it ourselves.
|
||||
if index >= input_len {
|
||||
throw_ub_format!(
|
||||
"`simd_extract` index {index} is out-of-bounds of vector with length {input_len}"
|
||||
);
|
||||
}
|
||||
self.copy_op(&self.project_index(&input, index)?, dest)?;
|
||||
}
|
||||
sym::likely | sym::unlikely | sym::black_box => {
|
||||
|
@ -563,9 +563,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let right_idx = src_index.checked_sub(left_len).unwrap();
|
||||
this.read_immediate(&this.project_index(&right, right_idx)?)?
|
||||
} else {
|
||||
span_bug!(
|
||||
this.cur_span(),
|
||||
"simd_shuffle index {src_index} is out of bounds for 2 vectors of size {left_len}",
|
||||
throw_ub_format!(
|
||||
"`simd_shuffle_generic` index {src_index} is out-of-bounds for 2 vectors with length {dest_len}"
|
||||
);
|
||||
};
|
||||
this.write_immediate(*val, &dest)?;
|
||||
@ -604,9 +603,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let right_idx = src_index.checked_sub(left_len).unwrap();
|
||||
this.read_immediate(&this.project_index(&right, right_idx)?)?
|
||||
} else {
|
||||
span_bug!(
|
||||
this.cur_span(),
|
||||
"simd_shuffle index {src_index} is out of bounds for 2 vectors of size {left_len}",
|
||||
throw_ub_format!(
|
||||
"`simd_shuffle` index {src_index} is out-of-bounds for 2 vectors with length {dest_len}"
|
||||
);
|
||||
};
|
||||
this.write_immediate(*val, &dest)?;
|
||||
|
8
src/tools/miri/tests/fail/intrinsics/simd-extract.rs
Normal file
8
src/tools/miri/tests/fail/intrinsics/simd-extract.rs
Normal file
@ -0,0 +1,8 @@
|
||||
#![feature(portable_simd, core_intrinsics)]
|
||||
use std::simd::*;
|
||||
|
||||
fn main() {
|
||||
let v = i32x4::splat(0);
|
||||
let _x: i32 = unsafe { std::intrinsics::simd::simd_extract(v, 4) };
|
||||
//~^ERROR: index 4 is out-of-bounds
|
||||
}
|
15
src/tools/miri/tests/fail/intrinsics/simd-extract.stderr
Normal file
15
src/tools/miri/tests/fail/intrinsics/simd-extract.stderr
Normal file
@ -0,0 +1,15 @@
|
||||
error: Undefined Behavior: `simd_extract` index 4 is out-of-bounds of vector with length 4
|
||||
--> $DIR/simd-extract.rs:LL:CC
|
||||
|
|
||||
LL | let _x: i32 = unsafe { std::intrinsics::simd::simd_extract(v, 4) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `simd_extract` index 4 is out-of-bounds of vector with length 4
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
= note: inside `main` at $DIR/simd-extract.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
Loading…
x
Reference in New Issue
Block a user