Skip to content

Commit 1e843a6

Browse files
authored
Unrolled build for rust-lang#121522
Rollup merge of rust-lang#121522 - RalfJung:insert-extract-boundscheck, r=oli-obk check that simd_insert/extract indices are in-bounds Fixes rust-lang#77477 r? `@oli-obk`
2 parents 6bdb8a4 + 134e2b2 commit 1e843a6

File tree

9 files changed

+112
-69
lines changed

9 files changed

+112
-69
lines changed

compiler/rustc_codegen_llvm/src/intrinsic.rs

+34-19
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
10791079
.map(|(arg_idx, val)| {
10801080
let idx = val.unwrap_leaf().try_to_i32().unwrap();
10811081
if idx >= i32::try_from(total_len).unwrap() {
1082-
bx.sess().dcx().emit_err(InvalidMonomorphization::ShuffleIndexOutOfBounds {
1082+
bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds {
10831083
span,
10841084
name,
10851085
arg_idx: arg_idx as u64,
@@ -1138,24 +1138,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
11381138
let val = bx.const_get_elt(vector, i as u64);
11391139
match bx.const_to_opt_u128(val, true) {
11401140
None => {
1141-
bx.sess().dcx().emit_err(
1142-
InvalidMonomorphization::ShuffleIndexNotConstant {
1143-
span,
1144-
name,
1145-
arg_idx,
1146-
},
1147-
);
1148-
None
1141+
bug!("typeck should have already ensured that these are const")
11491142
}
11501143
Some(idx) if idx >= total_len => {
1151-
bx.sess().dcx().emit_err(
1152-
InvalidMonomorphization::ShuffleIndexOutOfBounds {
1153-
span,
1154-
name,
1155-
arg_idx,
1156-
total_len,
1157-
},
1158-
);
1144+
bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds {
1145+
span,
1146+
name,
1147+
arg_idx,
1148+
total_len,
1149+
});
11591150
None
11601151
}
11611152
Some(idx) => Some(bx.const_i32(idx as i32)),
@@ -1184,18 +1175,42 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
11841175
out_ty: arg_tys[2]
11851176
}
11861177
);
1178+
let idx = bx
1179+
.const_to_opt_u128(args[1].immediate(), false)
1180+
.expect("typeck should have ensure that this is a const");
1181+
if idx >= in_len.into() {
1182+
bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds {
1183+
span,
1184+
name,
1185+
arg_idx: 1,
1186+
total_len: in_len.into(),
1187+
});
1188+
return Ok(bx.const_null(llret_ty));
1189+
}
11871190
return Ok(bx.insert_element(
11881191
args[0].immediate(),
11891192
args[2].immediate(),
1190-
args[1].immediate(),
1193+
bx.const_i32(idx as i32),
11911194
));
11921195
}
11931196
if name == sym::simd_extract {
11941197
require!(
11951198
ret_ty == in_elem,
11961199
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
11971200
);
1198-
return Ok(bx.extract_element(args[0].immediate(), args[1].immediate()));
1201+
let idx = bx
1202+
.const_to_opt_u128(args[1].immediate(), false)
1203+
.expect("typeck should have ensure that this is a const");
1204+
if idx >= in_len.into() {
1205+
bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds {
1206+
span,
1207+
name,
1208+
arg_idx: 1,
1209+
total_len: in_len.into(),
1210+
});
1211+
return Ok(bx.const_null(llret_ty));
1212+
}
1213+
return Ok(bx.extract_element(args[0].immediate(), bx.const_i32(idx as i32)));
11991214
}
12001215

12011216
if name == sym::simd_select {

compiler/rustc_codegen_ssa/messages.ftl

+2-4
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,12 @@ codegen_ssa_invalid_monomorphization_return_type = invalid monomorphization of `
106106
107107
codegen_ssa_invalid_monomorphization_second_argument_length = invalid monomorphization of `{$name}` intrinsic: expected second argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len}
108108
109-
codegen_ssa_invalid_monomorphization_shuffle_index_not_constant = invalid monomorphization of `{$name}` intrinsic: shuffle index #{$arg_idx} is not a constant
110-
111-
codegen_ssa_invalid_monomorphization_shuffle_index_out_of_bounds = invalid monomorphization of `{$name}` intrinsic: shuffle index #{$arg_idx} is out of bounds (limit {$total_len})
112-
113109
codegen_ssa_invalid_monomorphization_simd_argument = invalid monomorphization of `{$name}` intrinsic: expected SIMD argument type, found non-SIMD `{$ty}`
114110
115111
codegen_ssa_invalid_monomorphization_simd_first = invalid monomorphization of `{$name}` intrinsic: expected SIMD first type, found non-SIMD `{$ty}`
116112
113+
codegen_ssa_invalid_monomorphization_simd_index_out_of_bounds = invalid monomorphization of `{$name}` intrinsic: SIMD index #{$arg_idx} is out of bounds (limit {$total_len})
114+
117115
codegen_ssa_invalid_monomorphization_simd_input = invalid monomorphization of `{$name}` intrinsic: expected SIMD input type, found non-SIMD `{$ty}`
118116
119117
codegen_ssa_invalid_monomorphization_simd_return = invalid monomorphization of `{$name}` intrinsic: expected SIMD return type, found non-SIMD `{$ty}`

compiler/rustc_codegen_ssa/src/errors.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -797,16 +797,8 @@ pub enum InvalidMonomorphization<'tcx> {
797797
out_ty: Ty<'tcx>,
798798
},
799799

800-
#[diag(codegen_ssa_invalid_monomorphization_shuffle_index_not_constant, code = E0511)]
801-
ShuffleIndexNotConstant {
802-
#[primary_span]
803-
span: Span,
804-
name: Symbol,
805-
arg_idx: u64,
806-
},
807-
808-
#[diag(codegen_ssa_invalid_monomorphization_shuffle_index_out_of_bounds, code = E0511)]
809-
ShuffleIndexOutOfBounds {
800+
#[diag(codegen_ssa_invalid_monomorphization_simd_index_out_of_bounds, code = E0511)]
801+
SimdIndexOutOfBounds {
810802
#[primary_span]
811803
span: Span,
812804
name: Symbol,

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+

tests/ui/simd/shuffle-not-out-of-bounds.rs renamed to tests/ui/simd/not-out-of-bounds.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@ build-fail
22
#![allow(non_camel_case_types)]
3-
#![feature(repr_simd, platform_intrinsics)]
3+
#![feature(repr_simd, core_intrinsics)]
44

55
// Test for #73542 to verify out-of-bounds shuffle vectors do not compile.
66

@@ -28,9 +28,7 @@ struct u8x32([u8; 32]);
2828
#[derive(Copy, Clone)]
2929
struct u8x64([u8; 64]);
3030

31-
extern "platform-intrinsic" {
32-
pub fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
33-
}
31+
use std::intrinsics::simd::*;
3432

3533
// Test vectors by lane size. Since LLVM does not distinguish between a shuffle
3634
// over two f32s and a shuffle over two u64s, or any other such combination,
@@ -70,13 +68,16 @@ fn main() {
7068
test_shuffle_lanes!(32, u8x32, simd_shuffle);
7169
test_shuffle_lanes!(64, u8x64, simd_shuffle);
7270

73-
extern "platform-intrinsic" {
74-
fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
75-
}
7671
let v = u8x2([0, 0]);
7772
const I: [u32; 2] = [4, 4];
7873
unsafe {
7974
let _: u8x2 = simd_shuffle(v, v, I);
8075
//~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
8176
}
77+
78+
// also check insert/extract
79+
unsafe {
80+
simd_insert(v, 2, 0); //~ ERROR invalid monomorphization of `simd_insert` intrinsic
81+
let _val: u8 = simd_extract(v, 2); //~ ERROR invalid monomorphization of `simd_extract` intrinsic
82+
}
8283
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: shuffle index #0 is out of bounds (limit 4)
2-
--> $DIR/shuffle-not-out-of-bounds.rs:51:21
1+
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 4)
2+
--> $DIR/not-out-of-bounds.rs:49:21
33
|
44
LL | $y(vec1, vec2, ARR)
55
| ^^^^^^^^^^^^^^^^^^^
@@ -9,8 +9,8 @@ LL | test_shuffle_lanes!(2, u8x2, simd_shuffle);
99
|
1010
= note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
1111

12-
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: shuffle index #0 is out of bounds (limit 8)
13-
--> $DIR/shuffle-not-out-of-bounds.rs:51:21
12+
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 8)
13+
--> $DIR/not-out-of-bounds.rs:49:21
1414
|
1515
LL | $y(vec1, vec2, ARR)
1616
| ^^^^^^^^^^^^^^^^^^^
@@ -20,8 +20,8 @@ LL | test_shuffle_lanes!(4, u8x4, simd_shuffle);
2020
|
2121
= note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
2222

23-
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: shuffle index #0 is out of bounds (limit 16)
24-
--> $DIR/shuffle-not-out-of-bounds.rs:51:21
23+
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 16)
24+
--> $DIR/not-out-of-bounds.rs:49:21
2525
|
2626
LL | $y(vec1, vec2, ARR)
2727
| ^^^^^^^^^^^^^^^^^^^
@@ -31,8 +31,8 @@ LL | test_shuffle_lanes!(8, u8x8, simd_shuffle);
3131
|
3232
= note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
3333

34-
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: shuffle index #0 is out of bounds (limit 32)
35-
--> $DIR/shuffle-not-out-of-bounds.rs:51:21
34+
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 32)
35+
--> $DIR/not-out-of-bounds.rs:49:21
3636
|
3737
LL | $y(vec1, vec2, ARR)
3838
| ^^^^^^^^^^^^^^^^^^^
@@ -42,8 +42,8 @@ LL | test_shuffle_lanes!(16, u8x16, simd_shuffle);
4242
|
4343
= note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
4444

45-
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: shuffle index #0 is out of bounds (limit 64)
46-
--> $DIR/shuffle-not-out-of-bounds.rs:51:21
45+
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 64)
46+
--> $DIR/not-out-of-bounds.rs:49:21
4747
|
4848
LL | $y(vec1, vec2, ARR)
4949
| ^^^^^^^^^^^^^^^^^^^
@@ -53,8 +53,8 @@ LL | test_shuffle_lanes!(32, u8x32, simd_shuffle);
5353
|
5454
= note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
5555

56-
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: shuffle index #0 is out of bounds (limit 128)
57-
--> $DIR/shuffle-not-out-of-bounds.rs:51:21
56+
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 128)
57+
--> $DIR/not-out-of-bounds.rs:49:21
5858
|
5959
LL | $y(vec1, vec2, ARR)
6060
| ^^^^^^^^^^^^^^^^^^^
@@ -64,12 +64,24 @@ LL | test_shuffle_lanes!(64, u8x64, simd_shuffle);
6464
|
6565
= note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
6666

67-
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: shuffle index #0 is out of bounds (limit 4)
68-
--> $DIR/shuffle-not-out-of-bounds.rs:79:23
67+
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 4)
68+
--> $DIR/not-out-of-bounds.rs:74:23
6969
|
7070
LL | let _: u8x2 = simd_shuffle(v, v, I);
7171
| ^^^^^^^^^^^^^^^^^^^^^
7272

73-
error: aborting due to 7 previous errors
73+
error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected inserted type `u8` (element of input `u8x2`), found `i32`
74+
--> $DIR/not-out-of-bounds.rs:80:9
75+
|
76+
LL | simd_insert(v, 2, 0);
77+
| ^^^^^^^^^^^^^^^^^^^^
78+
79+
error[E0511]: invalid monomorphization of `simd_extract` intrinsic: SIMD index #1 is out of bounds (limit 2)
80+
--> $DIR/not-out-of-bounds.rs:81:24
81+
|
82+
LL | let _val: u8 = simd_extract(v, 2);
83+
| ^^^^^^^^^^^^^^^^^^
84+
85+
error: aborting due to 9 previous errors
7486

7587
For more information about this error, try `rustc --explain E0511`.

0 commit comments

Comments
 (0)