about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-08-06 22:45:42 +0200
committerRalf Jung <post@ralfj.de>2024-08-09 11:08:08 +0200
commitdec5b463fbe506302d7a63fa8c52dfc22b4b110f (patch)
treea84ee21a00ea4eb84e7e24c1a45f1c931104a65b
parent5cab8ae4a4a033acb25d629871deb24db19b638b (diff)
downloadrust-dec5b463fbe506302d7a63fa8c52dfc22b4b110f.tar.gz
rust-dec5b463fbe506302d7a63fa8c52dfc22b4b110f.zip
do not make function addresses unique with cross_crate_inline_threshold=always (even if that breaks backtraces)
-rw-r--r--src/tools/miri/src/machine.rs34
1 files changed, 20 insertions, 14 deletions
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index df4154bcb58..411619ed6b9 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -24,6 +24,7 @@ use rustc_middle::{
         Instance, Ty, TyCtxt,
     },
 };
+use rustc_session::config::InliningThreshold;
 use rustc_span::def_id::{CrateNum, DefId};
 use rustc_span::{Span, SpanData, Symbol};
 use rustc_target::abi::{Align, Size};
@@ -1525,24 +1526,29 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         instance: Option<ty::Instance<'tcx>>,
     ) -> usize {
         let unique = if let Some(instance) = instance {
-            // Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
-            // by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be
-            // duplicated across crates. We thus generate a new `AllocId` for every mention of a
-            // function. This means that `main as fn() == main as fn()` is false, while `let x = main as
-            // fn(); x == x` is true. However, as a quality-of-life feature it can be useful to identify
-            // certain functions uniquely, e.g. for backtraces. So we identify whether codegen will
-            // actually emit duplicate functions. It does that when they have non-lifetime generics, or
-            // when they can be inlined. All other functions are given a unique address.
-            // This is not a stable guarantee! The `inline` attribute is a hint and cannot be relied
-            // upon for anything. But if we don't do this, backtraces look terrible.
+            // Functions cannot be identified by pointers, as asm-equal functions can get
+            // deduplicated by the linker (we set the "unnamed_addr" attribute for LLVM) and
+            // functions can be duplicated across crates. We thus generate a new `AllocId` for every
+            // mention of a function. This means that `main as fn() == main as fn()` is false, while
+            // `let x = main as fn(); x == x` is true. However, as a quality-of-life feature it can
+            // be useful to identify certain functions uniquely, e.g. for backtraces. So we identify
+            // whether codegen will actually emit duplicate functions. It does that when they have
+            // non-lifetime generics, or when they can be inlined. All other functions are given a
+            // unique address. This is not a stable guarantee! The `inline` attribute is a hint and
+            // cannot be relied upon for anything. But if we don't do this, the
+            // `__rust_begin_short_backtrace`/`__rust_end_short_backtrace` logic breaks and panic
+            // backtraces look terrible.
             let is_generic = instance
                 .args
                 .into_iter()
                 .any(|kind| !matches!(kind.unpack(), ty::GenericArgKind::Lifetime(_)));
-            let can_be_inlined = match ecx.tcx.codegen_fn_attrs(instance.def_id()).inline {
-                InlineAttr::Never => false,
-                _ => true,
-            };
+            let can_be_inlined = matches!(
+                ecx.tcx.sess.opts.unstable_opts.cross_crate_inline_threshold,
+                InliningThreshold::Always
+            ) || !matches!(
+                ecx.tcx.codegen_fn_attrs(instance.def_id()).inline,
+                InlineAttr::Never
+            );
             !is_generic && !can_be_inlined
         } else {
             // Non-functions are never unique.