From 1b446cdbf03d26f31f6113a4ccb2e011f3a9abf1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 23 Jul 2020 13:07:21 +0200 Subject: [PATCH 1/3] replace miri_start_panic intrinsic by 'extern fn' --- src/libcore/intrinsics.rs | 8 -------- src/libpanic_unwind/miri.rs | 7 ++++++- src/librustc_codegen_ssa/mir/block.rs | 5 ----- src/librustc_span/symbol.rs | 1 - src/librustc_typeck/check/intrinsic.rs | 6 ------ 5 files changed, 6 insertions(+), 21 deletions(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 1af4f1009d1ac..71780361d298e 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1947,14 +1947,6 @@ extern "rust-intrinsic" { #[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "41079")] pub fn ptr_offset_from(ptr: *const T, base: *const T) -> isize; - /// Internal hook used by Miri to implement unwinding. - /// ICEs when encountered during non-Miri codegen. - /// - /// The `payload` ptr here will be exactly the one `do_catch` gets passed by `try`. - /// - /// Perma-unstable: do not use. - pub fn miri_start_panic(payload: *mut u8) -> !; - /// Internal placeholder for injecting code coverage counters when the "instrument-coverage" /// option is enabled. The placeholder is replaced with `llvm.instrprof.increment` during code /// generation. diff --git a/src/libpanic_unwind/miri.rs b/src/libpanic_unwind/miri.rs index 9d92b2b2f3207..d941b73b5fac1 100644 --- a/src/libpanic_unwind/miri.rs +++ b/src/libpanic_unwind/miri.rs @@ -6,11 +6,16 @@ use core::any::Any; // Must be pointer-sized. type Payload = Box>; +extern "Rust" { + /// Miri-provided extern function to begin unwinding. + fn miri_start_panic(payload: *mut u8) -> !; +} + pub unsafe fn panic(payload: Box) -> u32 { // The payload we pass to `miri_start_panic` will be exactly the argument we get // in `cleanup` below. So we just box it up once, to get something pointer-sized. let payload_box: Payload = Box::new(payload); - core::intrinsics::miri_start_panic(Box::into_raw(payload_box) as *mut u8) + miri_start_panic(Box::into_raw(payload_box) as *mut u8) } pub unsafe fn cleanup(payload_box: *mut u8) -> Box { diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index e1de9677f807a..f9e1094ff7304 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -606,11 +606,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return; } - // For normal codegen, this Miri-specific intrinsic should never occur. - if intrinsic == Some(sym::miri_start_panic) { - bug!("`miri_start_panic` should never end up in compiled code"); - } - if self.codegen_panic_intrinsic( &helper, &mut bx, diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index 22a5115c7f556..dadf040304d46 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -677,7 +677,6 @@ symbols! { minnumf32, minnumf64, mips_target_feature, - miri_start_panic, mmx_target_feature, module, module_path, diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index a09edf575c807..dc2172650e574 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -379,12 +379,6 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { sym::nontemporal_store => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()), - sym::miri_start_panic => { - // FIXME - the relevant types aren't lang items, - // so it's not trivial to check this - return; - } - sym::count_code_region => { (0, vec![tcx.types.u64, tcx.types.u32, tcx.types.u32, tcx.types.u32], tcx.mk_unit()) } From c8229cdfc1a570b73d826cb92dd2d43db5257e4a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 23 Jul 2020 15:49:39 +0200 Subject: [PATCH 2/3] on Windows, use miri_static_root for TLS dtors --- src/librustc_mir/interpret/memory.rs | 5 ++++- src/libstd/sys/windows/thread_local_key.rs | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 8af1a8ac608ac..ae837f8e16533 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -716,7 +716,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } } - pub fn leak_report(&self) -> usize { + /// Print leaked memory. Allocations reachable from `static_roots` or a `Global` allocation + /// are not considered leaked. Leaks whose kind `may_leak()` returns true are not reported. + pub fn leak_report(&self, static_roots: &[AllocId]) -> usize { // Collect the set of allocations that are *reachable* from `Global` allocations. let reachable = { let mut reachable = FxHashSet::default(); @@ -724,6 +726,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { let mut todo: Vec<_> = self.alloc_map.filter_map_collect(move |&id, &(kind, _)| { if Some(kind) == global_kind { Some(id) } else { None } }); + todo.extend(static_roots); while let Some(id) = todo.pop() { if reachable.insert(id) { // This is a new allocation, add its relocations to `todo`. diff --git a/src/libstd/sys/windows/thread_local_key.rs b/src/libstd/sys/windows/thread_local_key.rs index e0bb102b3afe5..0bd9600b6f2e1 100644 --- a/src/libstd/sys/windows/thread_local_key.rs +++ b/src/libstd/sys/windows/thread_local_key.rs @@ -110,6 +110,16 @@ struct Node { next: *mut Node, } +#[cfg(miri)] +extern "Rust" { + /// Miri-provided extern function to mark the block `ptr` points to as a "root" + /// for some static memory. This memory and everything reachable by it is not + /// considered leaking even if it still exists when the program terminates. + /// + /// `ptr` has to point to the beginning of an allocated block. + fn miri_static_root(ptr: *const u8); +} + unsafe fn register_dtor(key: Key, dtor: Dtor) { let mut node = Box::new(Node { key, dtor, next: ptr::null_mut() }); @@ -117,7 +127,12 @@ unsafe fn register_dtor(key: Key, dtor: Dtor) { loop { node.next = head; match DTORS.compare_exchange(head, &mut *node, SeqCst, SeqCst) { - Ok(_) => return mem::forget(node), + Ok(_) => { + #[cfg(miri)] + miri_static_root(&*node as *const _ as *const u8); + + return mem::forget(node); + } Err(cur) => head = cur, } } From 67b4f3b1482971f6eaecec0c5e01f8be467c491a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 23 Jul 2020 17:06:33 +0200 Subject: [PATCH 3/3] avoid implicitly returning () --- src/libstd/sys/windows/thread_local_key.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libstd/sys/windows/thread_local_key.rs b/src/libstd/sys/windows/thread_local_key.rs index 0bd9600b6f2e1..82901871e78ae 100644 --- a/src/libstd/sys/windows/thread_local_key.rs +++ b/src/libstd/sys/windows/thread_local_key.rs @@ -131,7 +131,8 @@ unsafe fn register_dtor(key: Key, dtor: Dtor) { #[cfg(miri)] miri_static_root(&*node as *const _ as *const u8); - return mem::forget(node); + mem::forget(node); + return; } Err(cur) => head = cur, }