about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libcore/intrinsics.rs8
-rw-r--r--src/libpanic_unwind/miri.rs7
-rw-r--r--src/librustc_codegen_ssa/mir/block.rs5
-rw-r--r--src/librustc_mir/interpret/memory.rs5
-rw-r--r--src/librustc_span/symbol.rs1
-rw-r--r--src/librustc_typeck/check/intrinsic.rs6
-rw-r--r--src/libstd/sys/windows/thread_local_key.rs18
7 files changed, 27 insertions, 23 deletions
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 1af4f1009d1..71780361d29 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<T>(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 9d92b2b2f32..d941b73b5fa 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<Box<dyn Any + Send>>;
 
+extern "Rust" {
+    /// Miri-provided extern function to begin unwinding.
+    fn miri_start_panic(payload: *mut u8) -> !;
+}
+
 pub unsafe fn panic(payload: Box<dyn Any + Send>) -> 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<dyn Any + Send> {
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index e1de9677f80..f9e1094ff73 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_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 8af1a8ac608..ae837f8e165 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/librustc_span/symbol.rs b/src/librustc_span/symbol.rs
index 22a5115c7f5..dadf040304d 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 a09edf575c8..dc2172650e5 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())
             }
diff --git a/src/libstd/sys/windows/thread_local_key.rs b/src/libstd/sys/windows/thread_local_key.rs
index e0bb102b3af..82901871e78 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,13 @@ 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);
+
+                mem::forget(node);
+                return;
+            }
             Err(cur) => head = cur,
         }
     }