From ae48c4ce2cc5d3dafe5f2f0733a92fd871907f65 Mon Sep 17 00:00:00 2001 From: Ramon de C Valle Date: Thu, 21 Mar 2024 13:29:24 -0700 Subject: [PATCH] CFI: Fix encode_ty: unexpected 'CoroutineWitness' Fix #122705 by adding support for encoding `ty:CoroutineClosure`. --- .../src/typeid/typeid_itanium_cxx_abi.rs | 8 +++++++- .../sanitizer/cfi-async-closure-issue-122705.rs | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/ui/sanitizer/cfi-async-closure-issue-122705.rs diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 06a07678dc621..e6423c0caa45b 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -1278,6 +1278,13 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio ); } + ty::CoroutineClosure(_, args) => { + // Transform async closures into function pointers + let fn_ptr = args.as_coroutine_closure().signature_parts_ty(); + // Transform fn_sig inputs and output + ty = transform_ty(tcx, fn_ptr, options); + } + ty::Ref(region, ty0, ..) => { // Remove references from function items, closures, and Fn trait objects if ty0.is_fn_def() || ty0.is_closure() || is_dynamic_fn_trait(tcx, *ty0) { @@ -1364,7 +1371,6 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio ty::Bound(..) | ty::Error(..) - | ty::CoroutineClosure(..) | ty::CoroutineWitness(..) | ty::Infer(..) | ty::Placeholder(..) => { diff --git a/tests/ui/sanitizer/cfi-async-closure-issue-122705.rs b/tests/ui/sanitizer/cfi-async-closure-issue-122705.rs new file mode 100644 index 0000000000000..2f86d2e9fe61c --- /dev/null +++ b/tests/ui/sanitizer/cfi-async-closure-issue-122705.rs @@ -0,0 +1,15 @@ +// Verifies that using async closure works. +// +//@ needs-sanitizer-cfi +//@ compile-flags: -Clto -Cprefer-dynamic=off -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0 --edition=2021 +//@ run-pass + +#![feature(async_closure)] + +#[inline(never)] +fn foo(_: T) {} + +fn main() { + let a = async move |_: i32, _: i32| {}; + foo(a); +}