From fb2c27d73f3528da5585bc7e49254164e0a2a5a2 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Wed, 28 Dec 2022 14:31:31 -0800 Subject: [PATCH] CFI: Monomorphize transparent ADTs before typeid Monomorphise `#[repr(transparent)]` parameterized ADTs before turning them into an Itanium mangled String. `#[repr(transparent)]` ADTs currently use the single field to represent them in their CFI type ID to ensure that they are compatible. However, if that type involves a type parameter instantiated at the ADT level, as in `ManuallyDrop`, this will currently ICE as the `Parameter` type cannot be mangled. Since this happens at lowering time, it should always be concrete after substitution. Fixes #106230 --- .../src/typeid/typeid_itanium_cxx_abi.rs | 5 ++++- ...i-emit-type-metadata-id-itanium-cxx-abi.rs | 22 ++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) 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 493e31a688fcc..e9b85705086b5 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 @@ -164,6 +164,7 @@ fn encode_const<'tcx>( /// Encodes a FnSig using the Itanium C++ ABI with vendor extended type qualifiers and types for /// Rust types that are not used at the FFI boundary. +#[instrument(level = "trace", skip(tcx, dict))] fn encode_fnsig<'tcx>( tcx: TyCtxt<'tcx>, fn_sig: &FnSig<'tcx>, @@ -653,6 +654,7 @@ fn encode_ty<'tcx>( // Transforms a ty:Ty for being encoded and used in the substitution dictionary. It transforms all // c_void types into unit types unconditionally, and generalizes all pointers if // TransformTyOptions::GENERALIZE_POINTERS option is set. +#[instrument(level = "trace", skip(tcx))] fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptions) -> Ty<'tcx> { let mut ty = ty; @@ -698,7 +700,7 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio !is_zst }); if let Some(field) = field { - let ty0 = tcx.type_of(field.did); + let ty0 = tcx.bound_type_of(field.did).subst(tcx, substs); // Generalize any repr(transparent) user-defined type that is either a pointer // or reference, and either references itself or any other type that contains or // references itself, to avoid a reference cycle. @@ -827,6 +829,7 @@ fn transform_substs<'tcx>( /// Returns a type metadata identifier for the specified FnAbi using the Itanium C++ ABI with vendor /// extended type qualifiers and types for Rust types that are not used at the FFI boundary. +#[instrument(level = "trace", skip(tcx))] pub fn typeid_for_fnabi<'tcx>( tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, diff --git a/src/test/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs b/src/test/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs index ece2adbdf4325..b9c33914360ba 100644 --- a/src/test/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs +++ b/src/test/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs @@ -131,6 +131,13 @@ pub struct Type13<'a> { member3: &'a Type13<'a>, } +// Helper type to allow `Type14` to be a unique ID +pub struct Bar; + +// repr(transparent) parameterized type +#[repr(transparent)] +pub struct Type14(T); + pub fn foo0(_: ()) { } // CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] pub fn foo1(_: c_void, _: ()) { } @@ -425,6 +432,12 @@ pub fn foo145(_: Type13, _: Type13) { } // CHECK: define{{.*}}foo145{{.*}}!type ![[TYPE145:[0-9]+]] pub fn foo146(_: Type13, _: Type13, _: Type13) { } // CHECK: define{{.*}}foo146{{.*}}!type ![[TYPE146:[0-9]+]] +pub fn foo147(_: Type14) { } +// CHECK: define{{.*}}foo147{{.*}}!type ![[TYPE147:[0-9]+]] +pub fn foo148(_: Type14, _: Type14) { } +// CHECK: define{{.*}}foo148{{.*}}!type ![[TYPE148:[0-9]+]] +pub fn foo149(_: Type14, _: Type14, _: Type14) { } +// CHECK: define{{.*}}foo149{{.*}}!type ![[TYPE149:[0-9]+]] // CHECK: ![[TYPE0]] = !{i64 0, !"_ZTSFvvE"} // CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvvvE"} @@ -570,6 +583,9 @@ pub fn foo146(_: Type13, _: Type13, _: Type13) { } // CHECK: ![[TYPE141]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3FooE"} // CHECK: ![[TYPE142]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3FooS_E"} // CHECK: ![[TYPE143]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3FooS_S_E"} -// CHECK: ![[TYPE144]] = !{i64 0, !"_ZTSFvu3refIu3refIvEEE"} -// CHECK: ![[TYPE145]] = !{i64 0, !"_ZTSFvu3refIu3refIvEES0_E"} -// CHECK: ![[TYPE146]] = !{i64 0, !"_ZTSFvu3refIu3refIvEES0_S0_E"} +// CHECK: ![[TYPE144]] = !{i64 0, !"_ZTSFvu3refIvEE"} +// CHECK: ![[TYPE145]] = !{i64 0, !"_ZTSFvu3refIvES_E"} +// CHECK: ![[TYPE146]] = !{i64 0, !"_ZTSFvu3refIvES_S_E"} +// CHECK: ![[TYPE147]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3BarE +// CHECK: ![[TYPE148]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3BarS_E +// CHECK: ![[TYPE149]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3BarS_S_E