mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-22 03:44:24 +00:00
Rollup merge of #58324 - RalfJung:fn-ptr-eq, r=oli-obk
miri: give non-generic functions a stable address This makes Miri correctly handle format string parameters despite https://github.com/rust-lang/rust/issues/58320. Matching Miri PR: https://github.com/solson/miri/pull/626 r? @oli-obk
This commit is contained in:
commit
a09aa0fde1
@ -27,7 +27,7 @@ pub use self::pointer::{Pointer, PointerArithmetic};
|
||||
use std::fmt;
|
||||
use crate::mir;
|
||||
use crate::hir::def_id::DefId;
|
||||
use crate::ty::{self, TyCtxt, Instance};
|
||||
use crate::ty::{self, TyCtxt, Instance, subst::UnpackedKind};
|
||||
use crate::ty::layout::{self, Size};
|
||||
use std::io;
|
||||
use crate::rustc_serialize::{Encoder, Decodable, Encodable};
|
||||
@ -318,14 +318,29 @@ impl<'tcx> AllocMap<'tcx> {
|
||||
id
|
||||
}
|
||||
|
||||
/// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
|
||||
/// by the linker 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.
|
||||
pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> AllocId {
|
||||
let id = self.reserve();
|
||||
self.id_to_kind.insert(id, AllocKind::Function(instance));
|
||||
id
|
||||
// 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, formatting code relies on function identity (see #58320), so we only do
|
||||
// this for generic functions. Lifetime parameters are ignored.
|
||||
let is_generic = instance.substs.into_iter().any(|kind| {
|
||||
match kind.unpack() {
|
||||
UnpackedKind::Lifetime(_) => false,
|
||||
_ => true,
|
||||
}
|
||||
});
|
||||
if is_generic {
|
||||
// Get a fresh ID
|
||||
let id = self.reserve();
|
||||
self.id_to_kind.insert(id, AllocKind::Function(instance));
|
||||
id
|
||||
} else {
|
||||
// Deduplicate
|
||||
self.intern(AllocKind::Function(instance))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `None` in case the `AllocId` is dangling. An `EvalContext` can still have a
|
||||
|
Loading…
Reference in New Issue
Block a user