Skip to content

Commit a031ba9

Browse files
committed
CFI: Encode Coroutine Witnesses
Fixes #122705
1 parent 10a7aa1 commit a031ba9

File tree

2 files changed

+51
-7
lines changed

2 files changed

+51
-7
lines changed

compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs

+21-7
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,17 @@ fn encode_ty<'tcx>(
671671
typeid.push_str(&s);
672672
}
673673

674+
ty::CoroutineWitness(def_id, args, ..) => {
675+
// u<length><name>[I<element-type1..element-typeN>E], where <element-type> is <subst>,
676+
// as vendor extended type.
677+
let mut s = String::new();
678+
let name = encode_ty_name(tcx, *def_id);
679+
let _ = write!(s, "u{}{}", name.len(), &name);
680+
s.push_str(&encode_args(tcx, args, dict, options));
681+
compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
682+
typeid.push_str(&s);
683+
}
684+
674685
// Pointer types
675686
ty::Ref(region, ty0, ..) => {
676687
// [U3mut]u3refI<element-type>E as vendor extended type qualifier and type
@@ -732,12 +743,7 @@ fn encode_ty<'tcx>(
732743
}
733744

734745
// Unexpected types
735-
ty::Alias(..)
736-
| ty::Bound(..)
737-
| ty::Error(..)
738-
| ty::CoroutineWitness(..)
739-
| ty::Infer(..)
740-
| ty::Placeholder(..) => {
746+
ty::Alias(..) | ty::Bound(..) | ty::Error(..) | ty::Infer(..) | ty::Placeholder(..) => {
741747
bug!("encode_ty: unexpected `{:?}`", ty.kind());
742748
}
743749
};
@@ -790,7 +796,7 @@ fn transform_ty<'tcx>(
790796
options: TransformTyOptions,
791797
) -> Ty<'tcx> {
792798
match ty.kind() {
793-
ty::Float(..) | ty::Str | ty::Never | ty::Foreign(..) | ty::CoroutineWitness(..) => {}
799+
ty::Float(..) | ty::Str | ty::Never | ty::Foreign(..) => {}
794800

795801
ty::Bool => {
796802
if options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) {
@@ -934,6 +940,14 @@ fn transform_ty<'tcx>(
934940
ty = Ty::new_coroutine(tcx, *def_id, transform_args(tcx, args, parents, options));
935941
}
936942

943+
ty::CoroutineWitness(def_id, args) => {
944+
ty = Ty::new_coroutine_witness(
945+
tcx,
946+
*def_id,
947+
transform_args(tcx, args, parents, options),
948+
);
949+
}
950+
937951
ty::Ref(region, ty0, ..) => {
938952
if options.contains(TransformTyOptions::GENERALIZE_POINTERS) {
939953
if ty.is_mutable_ptr() {
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Check various forms of dynamic closure calls
2+
3+
//@ edition: 2021
4+
//@ revisions: cfi kcfi
5+
// FIXME(#122848) Remove only-linux once OSX CFI binaries work
6+
//@ only-linux
7+
//@ [cfi] needs-sanitizer-cfi
8+
//@ [kcfi] needs-sanitizer-kcfi
9+
//@ compile-flags: -C target-feature=-crt-static
10+
//@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
11+
//@ [cfi] compile-flags: -Z sanitizer=cfi
12+
//@ [kcfi] compile-flags: -Z sanitizer=kcfi
13+
//@ run-pass
14+
15+
#![feature(async_closure)]
16+
#![feature(async_fn_traits)]
17+
18+
use std::ops::AsyncFn;
19+
20+
#[inline(never)]
21+
fn identity<T>(x: T) -> T { x }
22+
23+
// We can't actually create a `dyn AsyncFn()`, because it's not object-safe, but we should check
24+
// that we don't bug out when we encounter one.
25+
26+
fn main() {
27+
let f = identity(async || ());
28+
let _ = f.async_call(());
29+
let _ = f();
30+
}

0 commit comments

Comments
 (0)