Skip to content

Commit f714984

Browse files
committed
interpret: do no ICE on OOB shuffle/insert/extract indices
1 parent 3d2dc49 commit f714984

File tree

4 files changed

+39
-14
lines changed

4 files changed

+39
-14
lines changed

compiler/rustc_const_eval/src/interpret/intrinsics.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -379,10 +379,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
379379
let (input, input_len) = self.operand_to_simd(&args[0])?;
380380
let (dest, dest_len) = self.place_to_simd(dest)?;
381381
assert_eq!(input_len, dest_len, "Return vector length must match input length");
382-
assert!(
383-
index < dest_len,
384-
"Index `{index}` must be in bounds of vector with length {dest_len}"
385-
);
382+
// Bounds are not checked by typeck so we have to do it ourselves.
383+
if index >= input_len {
384+
throw_ub_format!(
385+
"`simd_insert` index {index} is out-of-bounds of vector with length {input_len}"
386+
);
387+
}
386388

387389
for i in 0..dest_len {
388390
let place = self.project_index(&dest, i)?;
@@ -397,10 +399,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
397399
sym::simd_extract => {
398400
let index = u64::from(self.read_scalar(&args[1])?.to_u32()?);
399401
let (input, input_len) = self.operand_to_simd(&args[0])?;
400-
assert!(
401-
index < input_len,
402-
"index `{index}` must be in bounds of vector with length {input_len}"
403-
);
402+
// Bounds are not checked by typeck so we have to do it ourselves.
403+
if index >= input_len {
404+
throw_ub_format!(
405+
"`simd_extract` index {index} is out-of-bounds of vector with length {input_len}"
406+
);
407+
}
404408
self.copy_op(&self.project_index(&input, index)?, dest)?;
405409
}
406410
sym::likely | sym::unlikely | sym::black_box => {

src/tools/miri/src/shims/intrinsics/simd.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -563,9 +563,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
563563
let right_idx = src_index.checked_sub(left_len).unwrap();
564564
this.read_immediate(&this.project_index(&right, right_idx)?)?
565565
} else {
566-
span_bug!(
567-
this.cur_span(),
568-
"simd_shuffle index {src_index} is out of bounds for 2 vectors of size {left_len}",
566+
throw_ub_format!(
567+
"`simd_shuffle_generic` index {src_index} is out-of-bounds for 2 vectors with length {dest_len}"
569568
);
570569
};
571570
this.write_immediate(*val, &dest)?;
@@ -604,9 +603,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
604603
let right_idx = src_index.checked_sub(left_len).unwrap();
605604
this.read_immediate(&this.project_index(&right, right_idx)?)?
606605
} else {
607-
span_bug!(
608-
this.cur_span(),
609-
"simd_shuffle index {src_index} is out of bounds for 2 vectors of size {left_len}",
606+
throw_ub_format!(
607+
"`simd_shuffle` index {src_index} is out-of-bounds for 2 vectors with length {dest_len}"
610608
);
611609
};
612610
this.write_immediate(*val, &dest)?;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#![feature(portable_simd, core_intrinsics)]
2+
use std::simd::*;
3+
4+
fn main() {
5+
let v = i32x4::splat(0);
6+
let _x: i32 = unsafe { std::intrinsics::simd::simd_extract(v, 4) };
7+
//~^ERROR: index 4 is out-of-bounds
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: Undefined Behavior: `simd_extract` index 4 is out-of-bounds of vector with length 4
2+
--> $DIR/simd-extract.rs:LL:CC
3+
|
4+
LL | let _x: i32 = unsafe { std::intrinsics::simd::simd_extract(v, 4) };
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `simd_extract` index 4 is out-of-bounds of vector with length 4
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: BACKTRACE:
10+
= note: inside `main` at $DIR/simd-extract.rs:LL:CC
11+
12+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
13+
14+
error: aborting due to 1 previous error
15+

0 commit comments

Comments
 (0)