Skip to content

Commit 1eeacf8

Browse files
authored
Merge pull request #2236 from rust-lang/rustc-pull
2 parents d490003 + c4e613a commit 1eeacf8

15 files changed

+166
-57
lines changed

src/intrinsics/simd.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
640640
let (dest, dest_len) = this.project_to_simd(dest)?;
641641

642642
let index =
643-
generic_args[2].expect_const().try_to_valtree().unwrap().0.unwrap_branch();
643+
generic_args[2].expect_const().to_value().valtree.unwrap_branch();
644644
let index_len = index.len();
645645

646646
assert_eq!(left_len, right_len);

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ pub const MIRI_DEFAULT_ARGS: &[&str] = &[
168168
"-Zmir-emit-retag",
169169
"-Zmir-keep-place-mention",
170170
"-Zmir-opt-level=0",
171-
"-Zmir-enable-passes=-CheckAlignment",
171+
"-Zmir-enable-passes=-CheckAlignment,-CheckNull",
172172
// Deduplicating diagnostics means we miss events when tracking what happens during an
173173
// execution. Let's not do that.
174174
"-Zdeduplicate-diagnostics=no",

src/machine.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use std::{fmt, process};
1111
use rand::rngs::StdRng;
1212
use rand::{Rng, SeedableRng};
1313
use rustc_abi::{Align, ExternAbi, Size};
14+
use rustc_apfloat::{Float, FloatConvert};
1415
use rustc_attr_parsing::InlineAttr;
1516
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1617
#[allow(unused)]
@@ -1129,20 +1130,24 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
11291130
}
11301131

11311132
#[inline(always)]
1132-
fn generate_nan<
1133-
F1: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F2>,
1134-
F2: rustc_apfloat::Float,
1135-
>(
1133+
fn generate_nan<F1: Float + FloatConvert<F2>, F2: Float>(
11361134
ecx: &InterpCx<'tcx, Self>,
11371135
inputs: &[F1],
11381136
) -> F2 {
11391137
ecx.generate_nan(inputs)
11401138
}
11411139

1140+
#[inline(always)]
1141+
fn equal_float_min_max<F: Float>(ecx: &MiriInterpCx<'tcx>, a: F, b: F) -> F {
1142+
ecx.equal_float_min_max(a, b)
1143+
}
1144+
1145+
#[inline(always)]
11421146
fn ub_checks(ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool> {
11431147
interp_ok(ecx.tcx.sess.ub_checks())
11441148
}
11451149

1150+
#[inline(always)]
11461151
fn thread_local_static_pointer(
11471152
ecx: &mut MiriInterpCx<'tcx>,
11481153
def_id: DefId,

src/operator.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
115115
nan
116116
}
117117
}
118+
119+
fn equal_float_min_max<F: Float>(&self, a: F, b: F) -> F {
120+
let this = self.eval_context_ref();
121+
// Return one side non-deterministically.
122+
let mut rand = this.machine.rng.borrow_mut();
123+
if rand.gen() { a } else { b }
124+
}
118125
}

src/shims/alloc.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::iter;
2-
31
use rustc_abi::{Align, Size};
42
use rustc_ast::expand::allocator::AllocatorKind;
53

@@ -80,18 +78,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
8078
}
8179
}
8280

83-
fn malloc(&mut self, size: u64, zero_init: bool) -> InterpResult<'tcx, Pointer> {
81+
fn malloc(&mut self, size: u64, init: AllocInit) -> InterpResult<'tcx, Pointer> {
8482
let this = self.eval_context_mut();
8583
let align = this.malloc_align(size);
86-
let ptr = this.allocate_ptr(Size::from_bytes(size), align, MiriMemoryKind::C.into())?;
87-
if zero_init {
88-
// We just allocated this, the access is definitely in-bounds and fits into our address space.
89-
this.write_bytes_ptr(
90-
ptr.into(),
91-
iter::repeat(0u8).take(usize::try_from(size).unwrap()),
92-
)
93-
.unwrap();
94-
}
84+
let ptr = this.allocate_ptr(Size::from_bytes(size), align, MiriMemoryKind::C.into(), init)?;
9585
interp_ok(ptr.into())
9686
}
9787

@@ -115,6 +105,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
115105
Size::from_bytes(size),
116106
Align::from_bytes(align).unwrap(),
117107
MiriMemoryKind::C.into(),
108+
AllocInit::Uninit
118109
)?;
119110
this.write_pointer(ptr, &memptr)?;
120111
interp_ok(Scalar::from_i32(0))
@@ -134,7 +125,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
134125
let new_align = this.malloc_align(new_size);
135126
if this.ptr_is_null(old_ptr)? {
136127
// Here we must behave like `malloc`.
137-
self.malloc(new_size, /*zero_init*/ false)
128+
self.malloc(new_size, AllocInit::Uninit)
138129
} else {
139130
if new_size == 0 {
140131
// C, in their infinite wisdom, made this UB.
@@ -147,6 +138,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
147138
Size::from_bytes(new_size),
148139
new_align,
149140
MiriMemoryKind::C.into(),
141+
AllocInit::Uninit
150142
)?;
151143
interp_ok(new_ptr.into())
152144
}
@@ -187,6 +179,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
187179
Size::from_bytes(size),
188180
Align::from_bytes(align).unwrap(),
189181
MiriMemoryKind::C.into(),
182+
AllocInit::Uninit
190183
)?;
191184
interp_ok(ptr.into())
192185
}

src/shims/foreign_items.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::collections::hash_map::Entry;
22
use std::io::Write;
3-
use std::iter;
43
use std::path::Path;
54

65
use rustc_abi::{Align, AlignFromBytesError, Size};
@@ -9,6 +8,7 @@ use rustc_ast::expand::allocator::alloc_error_handler_name;
98
use rustc_hir::def::DefKind;
109
use rustc_hir::def_id::CrateNum;
1110
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
11+
use rustc_middle::mir::interpret::AllocInit;
1212
use rustc_middle::ty::Ty;
1313
use rustc_middle::{mir, ty};
1414
use rustc_span::Symbol;
@@ -442,7 +442,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
442442
let [size] = this.check_shim(abi, Conv::C, link_name, args)?;
443443
let size = this.read_target_usize(size)?;
444444
if size <= this.max_size_of_val().bytes() {
445-
let res = this.malloc(size, /*zero_init:*/ false)?;
445+
let res = this.malloc(size, AllocInit::Uninit)?;
446446
this.write_pointer(res, dest)?;
447447
} else {
448448
// If this does not fit in an isize, return null and, on Unix, set errno.
@@ -457,7 +457,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
457457
let items = this.read_target_usize(items)?;
458458
let elem_size = this.read_target_usize(elem_size)?;
459459
if let Some(size) = this.compute_size_in_bytes(Size::from_bytes(elem_size), items) {
460-
let res = this.malloc(size.bytes(), /*zero_init:*/ true)?;
460+
let res = this.malloc(size.bytes(), AllocInit::Zero)?;
461461
this.write_pointer(res, dest)?;
462462
} else {
463463
// On size overflow, return null and, on Unix, set errno.
@@ -509,6 +509,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
509509
Size::from_bytes(size),
510510
Align::from_bytes(align).unwrap(),
511511
memory_kind.into(),
512+
AllocInit::Uninit
512513
)?;
513514

514515
ecx.write_pointer(ptr, dest)
@@ -537,14 +538,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
537538
Size::from_bytes(size),
538539
Align::from_bytes(align).unwrap(),
539540
MiriMemoryKind::Rust.into(),
541+
AllocInit::Zero
540542
)?;
541-
542-
// We just allocated this, the access is definitely in-bounds.
543-
this.write_bytes_ptr(
544-
ptr.into(),
545-
iter::repeat(0u8).take(usize::try_from(size).unwrap()),
546-
)
547-
.unwrap();
548543
this.write_pointer(ptr, dest)
549544
});
550545
}
@@ -604,6 +599,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
604599
Size::from_bytes(new_size),
605600
align,
606601
MiriMemoryKind::Rust.into(),
602+
AllocInit::Uninit
607603
)?;
608604
this.write_pointer(new_ptr, dest)
609605
});

src/shims/unix/fs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
11091109
Size::from_bytes(size),
11101110
dirent_layout.align.abi,
11111111
MiriMemoryKind::Runtime.into(),
1112+
AllocInit::Uninit
11121113
)?;
11131114
let entry: Pointer = entry.into();
11141115

src/shims/unix/linux/mem.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
4949
Size::from_bytes(new_size),
5050
align,
5151
MiriMemoryKind::Mmap.into(),
52+
AllocInit::Zero
5253
)?;
53-
if let Some(increase) = new_size.checked_sub(old_size) {
54-
// We just allocated this, the access is definitely in-bounds and fits into our address space.
55-
// mmap guarantees new mappings are zero-init.
56-
this.write_bytes_ptr(
57-
ptr.wrapping_offset(Size::from_bytes(old_size), this).into(),
58-
std::iter::repeat(0u8).take(usize::try_from(increase).unwrap()),
59-
)
60-
.unwrap();
61-
}
6254

6355
interp_ok(Scalar::from_pointer(ptr, this))
6456
}

src/shims/unix/mem.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
111111
return interp_ok(this.eval_libc("MAP_FAILED"));
112112
}
113113

114-
let ptr =
115-
this.allocate_ptr(Size::from_bytes(map_length), align, MiriMemoryKind::Mmap.into())?;
116-
// We just allocated this, the access is definitely in-bounds and fits into our address space.
117-
// mmap guarantees new mappings are zero-init.
118-
this.write_bytes_ptr(
119-
ptr.into(),
120-
std::iter::repeat(0u8).take(usize::try_from(map_length).unwrap()),
121-
)
122-
.unwrap();
114+
let ptr = this.allocate_ptr(
115+
Size::from_bytes(map_length),
116+
align,
117+
MiriMemoryKind::Mmap.into(),
118+
// mmap guarantees new mappings are zero-init.
119+
AllocInit::Zero
120+
)?;
123121

124122
interp_ok(Scalar::from_pointer(ptr, this))
125123
}

src/shims/windows/foreign_items.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -253,22 +253,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
253253
this.read_target_isize(handle)?;
254254
let flags = this.read_scalar(flags)?.to_u32()?;
255255
let size = this.read_target_usize(size)?;
256-
let heap_zero_memory = 0x00000008; // HEAP_ZERO_MEMORY
257-
let zero_init = (flags & heap_zero_memory) == heap_zero_memory;
256+
const HEAP_ZERO_MEMORY: u32 = 0x00000008;
257+
let init = if (flags & HEAP_ZERO_MEMORY) == HEAP_ZERO_MEMORY {
258+
AllocInit::Zero
259+
} else {
260+
AllocInit::Uninit
261+
};
258262
// Alignment is twice the pointer size.
259263
// Source: <https://learn.microsoft.com/en-us/windows/win32/api/heapapi/nf-heapapi-heapalloc>
260264
let align = this.tcx.pointer_size().bytes().strict_mul(2);
261265
let ptr = this.allocate_ptr(
262266
Size::from_bytes(size),
263267
Align::from_bytes(align).unwrap(),
264268
MiriMemoryKind::WinHeap.into(),
269+
init
265270
)?;
266-
if zero_init {
267-
this.write_bytes_ptr(
268-
ptr.into(),
269-
iter::repeat(0u8).take(usize::try_from(size).unwrap()),
270-
)?;
271-
}
272271
this.write_pointer(ptr, dest)?;
273272
}
274273
"HeapFree" => {
@@ -300,6 +299,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
300299
Size::from_bytes(size),
301300
Align::from_bytes(align).unwrap(),
302301
MiriMemoryKind::WinHeap.into(),
302+
AllocInit::Uninit
303303
)?;
304304
this.write_pointer(new_ptr, dest)?;
305305
}

tests/pass/disjoint-array-accesses.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// This is a regression test for issue #135671 where a MIR refactor about arrays and their lengths
2+
// unexpectedly caused borrowck errors for disjoint borrows of array elements, for which we had no
3+
// tests. This is a collection of a few code samples from that issue.
4+
5+
//@revisions: stack tree
6+
//@[tree]compile-flags: -Zmiri-tree-borrows
7+
8+
struct Test {
9+
a: i32,
10+
b: i32,
11+
}
12+
13+
fn one() {
14+
let inputs: &mut [_] = &mut [Test { a: 0, b: 0 }];
15+
let a = &mut inputs[0].a;
16+
let b = &mut inputs[0].b;
17+
18+
*a = 0;
19+
*b = 1;
20+
}
21+
22+
fn two() {
23+
let slice = &mut [(0, 0)][..];
24+
std::mem::swap(&mut slice[0].0, &mut slice[0].1);
25+
}
26+
27+
fn three(a: &mut [(i32, i32)], i: usize, j: usize) -> (&mut i32, &mut i32) {
28+
(&mut a[i].0, &mut a[j].1)
29+
}
30+
31+
fn main() {
32+
one();
33+
two();
34+
three(&mut [(1, 2), (3, 4)], 0, 1);
35+
}

tests/pass/dyn-upcast.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ fn main() {
1010
replace_vptr();
1111
vtable_nop_cast();
1212
drop_principal();
13+
modulo_binder();
14+
modulo_assoc();
1315
}
1416

1517
fn vtable_nop_cast() {
@@ -482,3 +484,53 @@ fn drop_principal() {
482484
println!("before");
483485
drop(y);
484486
}
487+
488+
// Test for <https://github.com/rust-lang/rust/issues/135316>.
489+
fn modulo_binder() {
490+
trait Supertrait<T> {
491+
fn _print_numbers(&self, mem: &[usize; 100]) {
492+
println!("{mem:?}");
493+
}
494+
}
495+
impl<T> Supertrait<T> for () {}
496+
497+
trait Trait<T, U>: Supertrait<T> + Supertrait<U> {
498+
fn say_hello(&self, _: &usize) {
499+
println!("Hello!");
500+
}
501+
}
502+
impl<T, U> Trait<T, U> for () {}
503+
504+
(&() as &'static dyn for<'a> Trait<&'static (), &'a ()>
505+
as &'static dyn Trait<&'static (), &'static ()>)
506+
.say_hello(&0);
507+
}
508+
509+
// Test for <https://github.com/rust-lang/rust/issues/135315>.
510+
fn modulo_assoc() {
511+
trait Supertrait<T> {
512+
fn _print_numbers(&self, mem: &[usize; 100]) {
513+
println!("{mem:?}");
514+
}
515+
}
516+
impl<T> Supertrait<T> for () {}
517+
518+
trait Identity {
519+
type Selff;
520+
}
521+
impl<Selff> Identity for Selff {
522+
type Selff = Selff;
523+
}
524+
525+
trait Middle<T>: Supertrait<()> + Supertrait<T> {
526+
fn say_hello(&self, _: &usize) {
527+
println!("Hello!");
528+
}
529+
}
530+
impl<T> Middle<T> for () {}
531+
532+
trait Trait: Middle<<() as Identity>::Selff> {}
533+
impl Trait for () {}
534+
535+
(&() as &dyn Trait as &dyn Middle<()>).say_hello(&0);
536+
}

tests/pass/dyn-upcast.stdout

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ before
22
goodbye
33
before
44
goodbye
5+
Hello!
6+
Hello!

0 commit comments

Comments
 (0)