Skip to content

Commit aa42061

Browse files
committed
CFI: Fix fn items, closures, and Fn trait objects
Fix casting between function items, closures, and Fn trait objects by transforming function items, closures, and Fn trait objects into function pointers for encoding.
1 parent 85e449a commit aa42061

14 files changed

+677
-170
lines changed

compiler/rustc_middle/src/ty/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1841,7 +1841,7 @@ impl<'tcx> TyCtxt<'tcx> {
18411841
/// does not compute the full elaborated super-predicates but just the set of def-ids. It is used
18421842
/// to identify which traits may define a given associated type to help avoid cycle errors.
18431843
/// Returns a `DefId` iterator.
1844-
fn super_traits_of(self, trait_def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
1844+
pub fn super_traits_of(self, trait_def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
18451845
let mut set = FxHashSet::default();
18461846
let mut stack = vec![trait_def_id];
18471847

compiler/rustc_middle/src/ty/sty.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1836,6 +1836,11 @@ impl<'tcx> Ty<'tcx> {
18361836
self.0.0.flags
18371837
}
18381838

1839+
#[inline]
1840+
pub fn is_tuple(self) -> bool {
1841+
matches!(self.kind(), Tuple(..))
1842+
}
1843+
18391844
#[inline]
18401845
pub fn is_unit(self) -> bool {
18411846
match self.kind() {
@@ -2208,6 +2213,11 @@ impl<'tcx> Ty<'tcx> {
22082213
matches!(self.kind(), FnDef(..) | FnPtr(_))
22092214
}
22102215

2216+
#[inline]
2217+
pub fn is_fn_def(self) -> bool {
2218+
matches!(self.kind(), FnDef(..))
2219+
}
2220+
22112221
#[inline]
22122222
pub fn is_fn_ptr(self) -> bool {
22132223
matches!(self.kind(), FnPtr(_))

compiler/rustc_symbol_mangling/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@
9191
#![doc(rust_logo)]
9292
#![feature(rustdoc_internals)]
9393
#![allow(internal_features)]
94+
#![feature(iter_order_by)]
95+
#![feature(let_chains)]
9496

9597
#[macro_use]
9698
extern crate rustc_middle;

compiler/rustc_symbol_mangling/src/typeid.rs

+37-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
/// For more information about LLVM CFI and cross-language LLVM CFI support for the Rust compiler,
55
/// see design document in the tracking issue #89653.
66
use bitflags::bitflags;
7-
use rustc_middle::ty::{Instance, Ty, TyCtxt};
7+
use rustc_middle::ty::{Instance, List, Ty, TyCtxt};
88
use rustc_target::abi::call::FnAbi;
99
use std::hash::Hasher;
1010
use twox_hash::XxHash64;
@@ -27,7 +27,11 @@ pub fn typeid_for_fnabi<'tcx>(
2727
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
2828
options: TypeIdOptions,
2929
) -> String {
30-
typeid_itanium_cxx_abi::typeid_for_fnabi(tcx, fn_abi, options)
30+
typeid_itanium_cxx_abi::typeid_for_fnabi(
31+
tcx,
32+
&typeid_itanium_cxx_abi::transform_fnabi(tcx, &fn_abi, options, None),
33+
options,
34+
)
3135
}
3236

3337
/// Returns a type metadata identifier for the specified Instance.
@@ -36,7 +40,16 @@ pub fn typeid_for_instance<'tcx>(
3640
instance: &Instance<'tcx>,
3741
options: TypeIdOptions,
3842
) -> String {
39-
typeid_itanium_cxx_abi::typeid_for_instance(tcx, instance, options)
43+
let fn_abi = tcx
44+
.fn_abi_of_instance(tcx.param_env(instance.def_id()).and((*instance, List::empty())))
45+
.unwrap_or_else(|instance| {
46+
bug!("typeid_for_instance: couldn't get fn_abi of instance {:?}", instance)
47+
});
48+
typeid_itanium_cxx_abi::typeid_for_fnabi(
49+
tcx,
50+
&typeid_itanium_cxx_abi::transform_fnabi(tcx, &fn_abi, options, Some(instance)),
51+
options,
52+
)
4053
}
4154

4255
/// Returns a KCFI type metadata identifier for the specified FnAbi.
@@ -48,7 +61,14 @@ pub fn kcfi_typeid_for_fnabi<'tcx>(
4861
// A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the
4962
// xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.)
5063
let mut hash: XxHash64 = Default::default();
51-
hash.write(typeid_itanium_cxx_abi::typeid_for_fnabi(tcx, fn_abi, options).as_bytes());
64+
hash.write(
65+
typeid_itanium_cxx_abi::typeid_for_fnabi(
66+
tcx,
67+
&typeid_itanium_cxx_abi::transform_fnabi(tcx, &fn_abi, options, None),
68+
options,
69+
)
70+
.as_bytes(),
71+
);
5272
hash.finish() as u32
5373
}
5474

@@ -58,9 +78,21 @@ pub fn kcfi_typeid_for_instance<'tcx>(
5878
instance: &Instance<'tcx>,
5979
options: TypeIdOptions,
6080
) -> u32 {
81+
let fn_abi = tcx
82+
.fn_abi_of_instance(tcx.param_env(instance.def_id()).and((*instance, List::empty())))
83+
.unwrap_or_else(|instance| {
84+
bug!("typeid_for_instance: couldn't get fn_abi of instance {:?}", instance)
85+
});
6186
// A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the
6287
// xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.)
6388
let mut hash: XxHash64 = Default::default();
64-
hash.write(typeid_itanium_cxx_abi::typeid_for_instance(tcx, instance, options).as_bytes());
89+
hash.write(
90+
typeid_itanium_cxx_abi::typeid_for_fnabi(
91+
tcx,
92+
&typeid_itanium_cxx_abi::transform_fnabi(tcx, &fn_abi, options, Some(instance)),
93+
options,
94+
)
95+
.as_bytes(),
96+
);
6597
hash.finish() as u32
6698
}

0 commit comments

Comments
 (0)