Skip to content

Commit dec5b46

Browse files
committed
do not make function addresses unique with cross_crate_inline_threshold=always (even if that breaks backtraces)
1 parent 5cab8ae commit dec5b46

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

src/tools/miri/src/machine.rs

+20-14
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use rustc_middle::{
2424
Instance, Ty, TyCtxt,
2525
},
2626
};
27+
use rustc_session::config::InliningThreshold;
2728
use rustc_span::def_id::{CrateNum, DefId};
2829
use rustc_span::{Span, SpanData, Symbol};
2930
use rustc_target::abi::{Align, Size};
@@ -1525,24 +1526,29 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
15251526
instance: Option<ty::Instance<'tcx>>,
15261527
) -> usize {
15271528
let unique = if let Some(instance) = instance {
1528-
// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
1529-
// by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be
1530-
// duplicated across crates. We thus generate a new `AllocId` for every mention of a
1531-
// function. This means that `main as fn() == main as fn()` is false, while `let x = main as
1532-
// fn(); x == x` is true. However, as a quality-of-life feature it can be useful to identify
1533-
// certain functions uniquely, e.g. for backtraces. So we identify whether codegen will
1534-
// actually emit duplicate functions. It does that when they have non-lifetime generics, or
1535-
// when they can be inlined. All other functions are given a unique address.
1536-
// This is not a stable guarantee! The `inline` attribute is a hint and cannot be relied
1537-
// upon for anything. But if we don't do this, backtraces look terrible.
1529+
// Functions cannot be identified by pointers, as asm-equal functions can get
1530+
// deduplicated by the linker (we set the "unnamed_addr" attribute for LLVM) and
1531+
// functions can be duplicated across crates. We thus generate a new `AllocId` for every
1532+
// mention of a function. This means that `main as fn() == main as fn()` is false, while
1533+
// `let x = main as fn(); x == x` is true. However, as a quality-of-life feature it can
1534+
// be useful to identify certain functions uniquely, e.g. for backtraces. So we identify
1535+
// whether codegen will actually emit duplicate functions. It does that when they have
1536+
// non-lifetime generics, or when they can be inlined. All other functions are given a
1537+
// unique address. This is not a stable guarantee! The `inline` attribute is a hint and
1538+
// cannot be relied upon for anything. But if we don't do this, the
1539+
// `__rust_begin_short_backtrace`/`__rust_end_short_backtrace` logic breaks and panic
1540+
// backtraces look terrible.
15381541
let is_generic = instance
15391542
.args
15401543
.into_iter()
15411544
.any(|kind| !matches!(kind.unpack(), ty::GenericArgKind::Lifetime(_)));
1542-
let can_be_inlined = match ecx.tcx.codegen_fn_attrs(instance.def_id()).inline {
1543-
InlineAttr::Never => false,
1544-
_ => true,
1545-
};
1545+
let can_be_inlined = matches!(
1546+
ecx.tcx.sess.opts.unstable_opts.cross_crate_inline_threshold,
1547+
InliningThreshold::Always
1548+
) || !matches!(
1549+
ecx.tcx.codegen_fn_attrs(instance.def_id()).inline,
1550+
InlineAttr::Never
1551+
);
15461552
!is_generic && !can_be_inlined
15471553
} else {
15481554
// Non-functions are never unique.

0 commit comments

Comments
 (0)