Skip to content

Commit 8b6a4a9

Browse files
committed
Auto merge of rust-lang#118567 - RalfJung:miri, r=RalfJung
Miri subtree update r? `@ghost`
2 parents 7ceaf19 + 28f9fe3 commit 8b6a4a9

32 files changed

+105
-30
lines changed

src/tools/miri/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ Definite bugs found:
589589
* [`regex` incorrectly handling unaligned `Vec<u8>` buffers](https://www.reddit.com/r/rust/comments/vq3mmu/comment/ienc7t0?context=3)
590590
* [Incorrect use of `compare_exchange_weak` in `once_cell`](https://github.com/matklad/once_cell/issues/186)
591591
* [Dropping with unaligned pointers in `vec::IntoIter`](https://github.com/rust-lang/rust/pull/106084)
592+
* [Deallocating with the wrong layout in new specializations for in-place `Iterator::collect`](https://github.com/rust-lang/rust/pull/118460)
592593

593594
Violations of [Stacked Borrows] found that are likely bugs (but Stacked Borrows is currently just an experiment):
594595

src/tools/miri/rust-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3668a8af1b81447c4afa1f82f60d7b94b71a549f
1+
225e36cff9809948d6567ab16f75d7b087ea83a7

src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs

+3-12
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ pub struct Stacks {
3737
history: AllocHistory,
3838
/// The set of tags that have been exposed inside this allocation.
3939
exposed_tags: FxHashSet<BorTag>,
40-
/// Whether this memory has been modified since the last time the tag GC ran
41-
modified_since_last_gc: bool,
4240
}
4341

4442
/// Indicates which permissions to grant to the retagged pointer.
@@ -450,15 +448,10 @@ impl<'tcx> Stack {
450448
/// Integration with the BorTag garbage collector
451449
impl Stacks {
452450
pub fn remove_unreachable_tags(&mut self, live_tags: &FxHashSet<BorTag>) {
453-
if self.modified_since_last_gc {
454-
for (_stack_range, stack) in self.stacks.iter_mut_all() {
455-
if stack.len() > 64 {
456-
stack.retain(live_tags);
457-
}
458-
}
459-
self.history.retain(live_tags);
460-
self.modified_since_last_gc = false;
451+
for (_stack_range, stack) in self.stacks.iter_mut_all() {
452+
stack.retain(live_tags);
461453
}
454+
self.history.retain(live_tags);
462455
}
463456
}
464457

@@ -488,7 +481,6 @@ impl<'tcx> Stacks {
488481
stacks: RangeMap::new(size, stack),
489482
history: AllocHistory::new(id, item, machine),
490483
exposed_tags: FxHashSet::default(),
491-
modified_since_last_gc: false,
492484
}
493485
}
494486

@@ -503,7 +495,6 @@ impl<'tcx> Stacks {
503495
&mut FxHashSet<BorTag>,
504496
) -> InterpResult<'tcx>,
505497
) -> InterpResult<'tcx> {
506-
self.modified_since_last_gc = true;
507498
for (stack_range, stack) in self.stacks.iter_mut(range.start, range.size) {
508499
let mut dcx = dcx_builder.build(&mut self.history, Size::from_bytes(stack_range.start));
509500
f(stack, &mut dcx, &mut self.exposed_tags)?;

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

+40-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use rustc_apfloat::{Float, Round};
22
use rustc_middle::ty::layout::{HasParamEnv, LayoutOf};
33
use rustc_middle::{mir, ty, ty::FloatTy};
4+
use rustc_span::{sym, Symbol};
45
use rustc_target::abi::{Endian, HasDataLayout};
56

67
use crate::*;
@@ -25,7 +26,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
2526
| "floor"
2627
| "round"
2728
| "trunc"
28-
| "fsqrt" => {
29+
| "fsqrt"
30+
| "ctlz"
31+
| "cttz"
32+
| "bswap"
33+
| "bitreverse"
34+
=> {
2935
let [op] = check_arg_count(args)?;
3036
let (op, op_len) = this.operand_to_simd(op)?;
3137
let (dest, dest_len) = this.place_to_simd(dest)?;
@@ -38,6 +44,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
3844
Abs,
3945
Sqrt,
4046
Round(rustc_apfloat::Round),
47+
Numeric(Symbol),
4148
}
4249
let which = match intrinsic_name {
4350
"neg" => Op::MirOp(mir::UnOp::Neg),
@@ -47,6 +54,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
4754
"floor" => Op::Round(rustc_apfloat::Round::TowardNegative),
4855
"round" => Op::Round(rustc_apfloat::Round::NearestTiesToAway),
4956
"trunc" => Op::Round(rustc_apfloat::Round::TowardZero),
57+
"ctlz" => Op::Numeric(sym::ctlz),
58+
"cttz" => Op::Numeric(sym::cttz),
59+
"bswap" => Op::Numeric(sym::bswap),
60+
"bitreverse" => Op::Numeric(sym::bitreverse),
5061
_ => unreachable!(),
5162
};
5263

@@ -101,6 +112,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
101112
}
102113
}
103114
}
115+
Op::Numeric(name) => {
116+
assert!(op.layout.ty.is_integral());
117+
let size = op.layout.size;
118+
let bits = op.to_scalar().to_bits(size).unwrap();
119+
let extra = 128u128.checked_sub(u128::from(size.bits())).unwrap();
120+
let bits_out = match name {
121+
sym::ctlz => u128::from(bits.leading_zeros()).checked_sub(extra).unwrap(),
122+
sym::cttz => u128::from((bits << extra).trailing_zeros()).checked_sub(extra).unwrap(),
123+
sym::bswap => (bits << extra).swap_bytes(),
124+
sym::bitreverse => (bits << extra).reverse_bits(),
125+
_ => unreachable!(),
126+
};
127+
Scalar::from_uint(bits_out, size)
128+
}
104129
};
105130
this.write_scalar(val, &dest)?;
106131
}
@@ -126,7 +151,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
126151
| "fmin"
127152
| "saturating_add"
128153
| "saturating_sub"
129-
| "arith_offset" => {
154+
| "arith_offset"
155+
=> {
130156
use mir::BinOp;
131157

132158
let [left, right] = check_arg_count(args)?;
@@ -386,16 +412,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
386412
let (dest, dest_len) = this.place_to_simd(dest)?;
387413
let bitmask_len = dest_len.max(8);
388414

389-
assert!(mask.layout.ty.is_integral());
390415
assert!(bitmask_len <= 64);
391416
assert_eq!(bitmask_len, mask.layout.size.bits());
392417
assert_eq!(dest_len, yes_len);
393418
assert_eq!(dest_len, no_len);
394419
let dest_len = u32::try_from(dest_len).unwrap();
395420
let bitmask_len = u32::try_from(bitmask_len).unwrap();
396421

397-
let mask: u64 =
398-
this.read_scalar(mask)?.to_bits(mask.layout.size)?.try_into().unwrap();
422+
// The mask can be a single integer or an array.
423+
let mask: u64 = match mask.layout.ty.kind() {
424+
ty::Int(..) | ty::Uint(..) =>
425+
this.read_scalar(mask)?.to_bits(mask.layout.size)?.try_into().unwrap(),
426+
ty::Array(elem, _) if matches!(elem.kind(), ty::Uint(ty::UintTy::U8)) => {
427+
let mask_ty = this.machine.layouts.uint(mask.layout.size).unwrap();
428+
let mask = mask.transmute(mask_ty, this)?;
429+
this.read_scalar(&mask)?.to_bits(mask_ty.size)?.try_into().unwrap()
430+
}
431+
_ => bug!("simd_select_bitmask: invalid mask type {}", mask.layout.ty),
432+
};
433+
399434
for i in 0..dest_len {
400435
let mask = mask
401436
& 1u64

src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// We disable the GC for this test because it would change what is printed.
12
//@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
23

34
// Check how a Reserved with interior mutability

src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// We disable the GC for this test because it would change what is printed.
12
//@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
23

34
#[path = "../../../utils/mod.rs"]

src/tools/miri/tests/fail/uninit_buffer.rs renamed to src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//@compile-flags: -Zmiri-disable-validation
12
//@error-in-other-file: memory is uninitialized at [0x4..0x10]
23

34
#![allow(dropping_copy_types)]

src/tools/miri/tests/fail/uninit_buffer.stderr renamed to src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ LL | let mut order = unsafe { compare_bytes(left.as_ptr(), right.as_ptr(
1010
= note: inside `<u8 as core::slice::cmp::SliceOrd>::compare` at RUSTLIB/core/src/slice/cmp.rs:LL:CC
1111
= note: inside `core::slice::cmp::<impl std::cmp::Ord for [u8]>::cmp` at RUSTLIB/core/src/slice/cmp.rs:LL:CC
1212
note: inside `main`
13-
--> $DIR/uninit_buffer.rs:LL:CC
13+
--> $DIR/uninit_alloc_diagnostic.rs:LL:CC
1414
|
1515
LL | drop(slice1.cmp(slice2));
1616
| ^^^^^^^^^^^^^^^^^^

src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs renamed to src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//@compile-flags: -Zmiri-disable-validation
12
//@error-in-other-file: memory is uninitialized at [0x4..0x8]
23
//@normalize-stderr-test: "a[0-9]+" -> "ALLOC"
34
#![feature(strict_provenance)]

src/tools/miri/tests/fail/uninit_buffer_with_provenance.stderr renamed to src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ LL | let mut order = unsafe { compare_bytes(left.as_ptr(), right.as_ptr(
1010
= note: inside `<u8 as core::slice::cmp::SliceOrd>::compare` at RUSTLIB/core/src/slice/cmp.rs:LL:CC
1111
= note: inside `core::slice::cmp::<impl std::cmp::Ord for [u8]>::cmp` at RUSTLIB/core/src/slice/cmp.rs:LL:CC
1212
note: inside `main`
13-
--> $DIR/uninit_buffer_with_provenance.rs:LL:CC
13+
--> $DIR/uninit_alloc_diagnostic_with_provenance.rs:LL:CC
1414
|
1515
LL | drop(slice1.cmp(slice2));
1616
| ^^^^^^^^^^^^^^^^^^

src/tools/miri/tests/fail/invalid_bool.stderr renamed to src/tools/miri/tests/fail/validity/invalid_bool_op.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error: Undefined Behavior: interpreting an invalid 8-bit value as a bool: 0x02
2-
--> $DIR/invalid_bool.rs:LL:CC
2+
--> $DIR/invalid_bool_op.rs:LL:CC
33
|
44
LL | let _x = b == std::hint::black_box(true);
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ interpreting an invalid 8-bit value as a bool: 0x02
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
99
= note: BACKTRACE:
10-
= note: inside `main` at $DIR/invalid_bool.rs:LL:CC
10+
= note: inside `main` at $DIR/invalid_bool_op.rs:LL:CC
1111

1212
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1313

src/tools/miri/tests/fail/invalid_char.stderr renamed to src/tools/miri/tests/fail/validity/invalid_char_op.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error: Undefined Behavior: interpreting an invalid 32-bit value as a char: $HEX
2-
--> $DIR/invalid_char.rs:LL:CC
2+
--> $DIR/invalid_char_op.rs:LL:CC
33
|
44
LL | let _x = c == 'x';
55
| ^^^^^^^^ interpreting an invalid 32-bit value as a char: $HEX
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
99
= note: BACKTRACE:
10-
= note: inside `main` at $DIR/invalid_char.rs:LL:CC
10+
= note: inside `main` at $DIR/invalid_char_op.rs:LL:CC
1111

1212
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1313

src/tools/miri/tests/fail/invalid_enum_tag.stderr renamed to src/tools/miri/tests/fail/validity/invalid_enum_op.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error: Undefined Behavior: enum value has invalid tag: $HEX
2-
--> $DIR/invalid_enum_tag.rs:LL:CC
2+
--> $DIR/invalid_enum_op.rs:LL:CC
33
|
44
LL | let _val = mem::discriminant(&f);
55
| ^^^^^^^^^^^^^^^^^^^^^ enum value has invalid tag: $HEX
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
99
= note: BACKTRACE:
10-
= note: inside `main` at $DIR/invalid_enum_tag.rs:LL:CC
10+
= note: inside `main` at $DIR/invalid_enum_op.rs:LL:CC
1111

1212
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1313

src/tools/miri/tests/fail/invalid_int.stderr renamed to src/tools/miri/tests/fail/validity/invalid_int_op.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
2-
--> $DIR/invalid_int.rs:LL:CC
2+
--> $DIR/invalid_int_op.rs:LL:CC
33
|
44
LL | let i = unsafe { std::mem::MaybeUninit::<i32>::uninit().assume_init() };
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
99
= note: BACKTRACE:
10-
= note: inside `main` at $DIR/invalid_int.rs:LL:CC
10+
= note: inside `main` at $DIR/invalid_int_op.rs:LL:CC
1111

1212
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1313

src/tools/miri/tests/pass/concurrency/sync.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ fn check_conditional_variables_timed_wait_notimeout() {
8383
cvar.notify_one();
8484
});
8585

86-
let (_guard, timeout) = cvar.wait_timeout(guard, Duration::from_millis(500)).unwrap();
86+
let (_guard, timeout) = cvar.wait_timeout(guard, Duration::from_millis(1000)).unwrap();
8787
assert!(!timeout.timed_out());
8888
handle.join().unwrap();
8989
}

src/tools/miri/tests/pass/portable-simd.rs

+34
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,24 @@ fn simd_ops_i32() {
197197
assert_eq!(b.reduce_or(), -1);
198198
assert_eq!(a.reduce_xor(), 0);
199199
assert_eq!(b.reduce_xor(), -4);
200+
201+
assert_eq!(b.leading_zeros(), u32x4::from_array([31, 30, 30, 0]));
202+
assert_eq!(b.trailing_zeros(), u32x4::from_array([0, 1, 0, 2]));
203+
assert_eq!(b.leading_ones(), u32x4::from_array([0, 0, 0, 30]));
204+
assert_eq!(b.trailing_ones(), u32x4::from_array([1, 0, 2, 0]));
205+
assert_eq!(
206+
b.swap_bytes(),
207+
i32x4::from_array([0x01000000, 0x02000000, 0x03000000, 0xfcffffffu32 as i32])
208+
);
209+
assert_eq!(
210+
b.reverse_bits(),
211+
i32x4::from_array([
212+
0x80000000u32 as i32,
213+
0x40000000,
214+
0xc0000000u32 as i32,
215+
0x3fffffffu32 as i32
216+
])
217+
);
200218
}
201219

202220
fn simd_mask() {
@@ -247,6 +265,22 @@ fn simd_mask() {
247265
assert_eq!(bitmask2, [0b0001]);
248266
}
249267
}
268+
269+
// This used to cause an ICE.
270+
let bitmask = u8x8::from_array([0b01000101, 0, 0, 0, 0, 0, 0, 0]);
271+
assert_eq!(
272+
mask32x8::from_bitmask_vector(bitmask),
273+
mask32x8::from_array([true, false, true, false, false, false, true, false]),
274+
);
275+
let bitmask =
276+
u8x16::from_array([0b01000101, 0b11110000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
277+
assert_eq!(
278+
mask32x16::from_bitmask_vector(bitmask),
279+
mask32x16::from_array([
280+
true, false, true, false, false, false, true, false, false, false, false, false, true,
281+
true, true, true,
282+
]),
283+
);
250284
}
251285

252286
fn simd_cast() {

src/tools/miri/tests/pass/stacked-borrows/stack-printing.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
//@compile-flags: -Zmiri-permissive-provenance
1+
// We disable the GC for this test because it would change what is printed. We are testing the
2+
// printing, not how it interacts with the GC.
3+
//@compile-flags: -Zmiri-permissive-provenance -Zmiri-provenance-gc=0
4+
25
#![feature(strict_provenance)]
36
use std::{
47
alloc::{self, Layout},

src/tools/miri/tests/pass/tree_borrows/cell-alternate-writes.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// We disable the GC for this test because it would change what is printed.
12
//@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
23
#[path = "../../utils/mod.rs"]
34
#[macro_use]

src/tools/miri/tests/pass/tree_borrows/end-of-protector.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// We disable the GC for this test because it would change what is printed.
12
//@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
23

34
// Check that a protector goes back to normal behavior when the function

src/tools/miri/tests/pass/tree_borrows/formatting.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// We disable the GC for this test because it would change what is printed.
12
//@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
23

34
#[path = "../../utils/mod.rs"]

src/tools/miri/tests/pass/tree_borrows/reborrow-is-read.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// We disable the GC for this test because it would change what is printed.
12
//@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
23

34
#[path = "../../utils/mod.rs"]

src/tools/miri/tests/pass/tree_borrows/reserved.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// We disable the GC for this test because it would change what is printed.
12
//@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
23

34
#[path = "../../utils/mod.rs"]

src/tools/miri/tests/pass/tree_borrows/unique.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//@revisions: default uniq
2+
// We disable the GC for this test because it would change what is printed.
23
//@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
34
//@[uniq]compile-flags: -Zmiri-unique-is-unique
45

src/tools/miri/tests/pass/tree_borrows/vec_unique.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//@revisions: default uniq
2+
// We disable the GC for this test because it would change what is printed.
23
//@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
34
//@[uniq]compile-flags: -Zmiri-unique-is-unique
45

0 commit comments

Comments
 (0)