CFI: Fix encode_ty: unexpected Param(B/#1)
Fixes #111510 and complements #106547 by adding support for encoding type parameters and also by transforming trait objects' traits into their identities before emitting type checks.
This commit is contained in:
parent
077fc26f0a
commit
f067935ab2
4 changed files with 191 additions and 66 deletions
|
@ -673,6 +673,14 @@ fn encode_ty<'tcx>(
|
|||
typeid.push_str(&s);
|
||||
}
|
||||
|
||||
// Type parameters
|
||||
ty::Param(..) => {
|
||||
// u5param as vendor extended type
|
||||
let mut s = String::from("u5param");
|
||||
compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
|
||||
typeid.push_str(&s);
|
||||
}
|
||||
|
||||
// Unexpected types
|
||||
ty::Bound(..)
|
||||
| ty::Error(..)
|
||||
|
@ -680,7 +688,6 @@ fn encode_ty<'tcx>(
|
|||
| ty::GeneratorWitnessMIR(..)
|
||||
| ty::Infer(..)
|
||||
| ty::Alias(..)
|
||||
| ty::Param(..)
|
||||
| ty::Placeholder(..) => {
|
||||
bug!("encode_ty: unexpected `{:?}`", ty.kind());
|
||||
}
|
||||
|
@ -689,6 +696,41 @@ fn encode_ty<'tcx>(
|
|||
typeid
|
||||
}
|
||||
|
||||
/// Transforms predicates for being encoded and used in the substitution dictionary.
|
||||
fn transform_predicates<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
predicates: &List<ty::PolyExistentialPredicate<'tcx>>,
|
||||
_options: EncodeTyOptions,
|
||||
) -> &'tcx List<ty::PolyExistentialPredicate<'tcx>> {
|
||||
let predicates: Vec<ty::PolyExistentialPredicate<'tcx>> = predicates
|
||||
.iter()
|
||||
.map(|predicate| match predicate.skip_binder() {
|
||||
ty::ExistentialPredicate::Trait(trait_ref) => {
|
||||
let trait_ref = ty::TraitRef::identity(tcx, trait_ref.def_id);
|
||||
ty::Binder::dummy(ty::ExistentialPredicate::Trait(
|
||||
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref),
|
||||
))
|
||||
}
|
||||
_ => predicate,
|
||||
})
|
||||
.collect();
|
||||
tcx.mk_poly_existential_predicates(&predicates)
|
||||
}
|
||||
|
||||
/// Transforms substs for being encoded and used in the substitution dictionary.
|
||||
fn transform_substs<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
options: TransformTyOptions,
|
||||
) -> SubstsRef<'tcx> {
|
||||
let substs = substs.iter().map(|subst| match subst.unpack() {
|
||||
GenericArgKind::Type(ty) if ty.is_c_void(tcx) => tcx.mk_unit().into(),
|
||||
GenericArgKind::Type(ty) => transform_ty(tcx, ty, options).into(),
|
||||
_ => subst,
|
||||
});
|
||||
tcx.mk_substs_from_iter(substs)
|
||||
}
|
||||
|
||||
// Transforms a ty:Ty for being encoded and used in the substitution dictionary. It transforms all
|
||||
// c_void types into unit types unconditionally, generalizes pointers if
|
||||
// TransformTyOptions::GENERALIZE_POINTERS option is set, and normalizes integers if
|
||||
|
@ -697,7 +739,7 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
|
|||
let mut ty = ty;
|
||||
|
||||
match ty.kind() {
|
||||
ty::Float(..) | ty::Char | ty::Str | ty::Never | ty::Foreign(..) | ty::Dynamic(..) => {}
|
||||
ty::Float(..) | ty::Char | ty::Str | ty::Never | ty::Foreign(..) => {}
|
||||
|
||||
ty::Bool => {
|
||||
if options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) {
|
||||
|
@ -870,6 +912,14 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
|
|||
}
|
||||
}
|
||||
|
||||
ty::Dynamic(predicates, _region, kind) => {
|
||||
ty = tcx.mk_dynamic(
|
||||
transform_predicates(tcx, predicates, options),
|
||||
tcx.lifetimes.re_erased,
|
||||
*kind,
|
||||
);
|
||||
}
|
||||
|
||||
ty::Bound(..)
|
||||
| ty::Error(..)
|
||||
| ty::GeneratorWitness(..)
|
||||
|
@ -885,20 +935,6 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
|
|||
ty
|
||||
}
|
||||
|
||||
/// Transforms substs for being encoded and used in the substitution dictionary.
|
||||
fn transform_substs<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
options: TransformTyOptions,
|
||||
) -> SubstsRef<'tcx> {
|
||||
let substs = substs.iter().map(|subst| match subst.unpack() {
|
||||
GenericArgKind::Type(ty) if ty.is_c_void(tcx) => tcx.mk_unit().into(),
|
||||
GenericArgKind::Type(ty) => transform_ty(tcx, ty, options).into(),
|
||||
_ => subst,
|
||||
});
|
||||
tcx.mk_substs_from_iter(substs)
|
||||
}
|
||||
|
||||
/// 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))]
|
||||
|
|
|
@ -44,7 +44,7 @@ impl<T> Trait1<T> for i32 {
|
|||
}
|
||||
|
||||
// Trait implementation
|
||||
impl<T> Trait1<T> for Struct1<T> {
|
||||
impl<T, U> Trait1<T> for Struct1<U> {
|
||||
fn foo(&self) { }
|
||||
}
|
||||
|
||||
|
@ -536,15 +536,15 @@ pub fn foo149(_: Type14<Bar>, _: Type14<Bar>, _: Type14<Bar>) { }
|
|||
// CHECK: ![[TYPE93]] = !{i64 0, !"_ZTSFvPFu3i32S_EE"}
|
||||
// CHECK: ![[TYPE94]] = !{i64 0, !"_ZTSFvPFu3i32S_ES0_E"}
|
||||
// CHECK: ![[TYPE95]] = !{i64 0, !"_ZTSFvPFu3i32S_ES0_S0_E"}
|
||||
// CHECK: ![[TYPE96]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEEE"}
|
||||
// CHECK: ![[TYPE97]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_E"}
|
||||
// CHECK: ![[TYPE98]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_S5_E"}
|
||||
// CHECK: ![[TYPE99]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEEE"}
|
||||
// CHECK: ![[TYPE100]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_E"}
|
||||
// CHECK: ![[TYPE101]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_S5_E"}
|
||||
// CHECK: ![[TYPE102]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEEE"}
|
||||
// CHECK: ![[TYPE103]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_E"}
|
||||
// CHECK: ![[TYPE104]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_S5_E"}
|
||||
// CHECK: ![[TYPE96]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEEE"}
|
||||
// CHECK: ![[TYPE97]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEES6_E"}
|
||||
// CHECK: ![[TYPE98]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEES6_S6_E"}
|
||||
// CHECK: ![[TYPE99]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEEE"}
|
||||
// CHECK: ![[TYPE100]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEES6_E"}
|
||||
// CHECK: ![[TYPE101]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEES6_S6_E"}
|
||||
// CHECK: ![[TYPE102]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEEE"}
|
||||
// CHECK: ![[TYPE103]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEES6_E"}
|
||||
// CHECK: ![[TYPE104]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEES6_S6_E"}
|
||||
// CHECK: ![[TYPE105]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEEE"}
|
||||
// CHECK: ![[TYPE106]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEES2_E"}
|
||||
// CHECK: ![[TYPE107]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEES2_S2_E"}
|
||||
|
@ -566,9 +566,9 @@ pub fn foo149(_: Type14<Bar>, _: Type14<Bar>, _: Type14<Bar>) { }
|
|||
// CHECK: ![[TYPE123]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn18{{[{}][{}]}}impl{{[}][}]}}3fooIu3i32EE"}
|
||||
// CHECK: ![[TYPE124]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn18{{[{}][{}]}}impl{{[}][}]}}3fooIu3i32ES0_E"}
|
||||
// CHECK: ![[TYPE125]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn18{{[{}][{}]}}impl{{[}][}]}}3fooIu3i32ES0_S0_E"}
|
||||
// CHECK: ![[TYPE126]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait1Iu3i32Eu6regionES_EE"}
|
||||
// CHECK: ![[TYPE127]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait1Iu3i32Eu6regionES_ES3_E"}
|
||||
// CHECK: ![[TYPE128]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait1Iu3i32Eu6regionES_ES3_S3_E"}
|
||||
// CHECK: ![[TYPE126]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait1Iu5paramEu6regionEu3i32EE"}
|
||||
// CHECK: ![[TYPE127]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait1Iu5paramEu6regionEu3i32ES4_E"}
|
||||
// CHECK: ![[TYPE128]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait1Iu5paramEu6regionEu3i32ES4_S4_E"}
|
||||
// CHECK: ![[TYPE129]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3i32S_EE"}
|
||||
// CHECK: ![[TYPE130]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3i32S_ES0_E"}
|
||||
// CHECK: ![[TYPE131]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3i32S_ES0_S0_E"}
|
||||
|
|
|
@ -1,44 +1,89 @@
|
|||
// Verifies that type metadata identifiers for trait objects are emitted correctly.
|
||||
//
|
||||
// needs-sanitizer-cfi
|
||||
// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi
|
||||
// compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Ctarget-feature=-crt-static -Zsanitizer=cfi
|
||||
|
||||
#![crate_type="lib"]
|
||||
|
||||
trait Trait1 {
|
||||
pub trait Trait1 {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
struct Type1;
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Type1;
|
||||
|
||||
impl Trait1 for Type1 {
|
||||
fn foo(&self) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn foo() {
|
||||
let a = Type1;
|
||||
a.foo();
|
||||
// CHECK-LABEL: define{{.*}}foo{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call <sanitizer_cfi_emit_type_metadata_trait_objects::Type1 as sanitizer_cfi_emit_type_metadata_trait_objects::Trait1>::foo
|
||||
pub trait Trait2<T> {
|
||||
fn bar(&self);
|
||||
}
|
||||
|
||||
pub fn bar() {
|
||||
pub struct Type2;
|
||||
|
||||
impl Trait2<i32> for Type2 {
|
||||
fn bar(&self) {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Trait3<T> {
|
||||
fn baz(&self, _: &T);
|
||||
}
|
||||
|
||||
pub struct Type3;
|
||||
|
||||
impl<T, U> Trait3<U> for T {
|
||||
fn baz(&self, _: &U) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn foo1(a: &dyn Trait1) {
|
||||
a.foo();
|
||||
// CHECK-LABEL: define{{.*}}4foo1{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE1:[[:print:]]+]]")
|
||||
}
|
||||
|
||||
pub fn bar1() {
|
||||
let a = Type1;
|
||||
let b = &a as &dyn Trait1;
|
||||
b.foo();
|
||||
// CHECK-LABEL: define{{.*}}bar{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0|%1}}, metadata !"[[TYPE1:[[:print:]]+]]")
|
||||
// CHECK-LABEL: define{{.*}}4bar1{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE2:[[:print:]]+]]")
|
||||
}
|
||||
|
||||
pub fn baz() {
|
||||
let a = Type1;
|
||||
let b = &a as &dyn Trait1;
|
||||
a.foo();
|
||||
b.foo();
|
||||
// CHECK-LABEL: define{{.*}}baz{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call <sanitizer_cfi_emit_type_metadata_trait_objects::Type1 as sanitizer_cfi_emit_type_metadata_trait_objects::Trait1>::foo
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0|%1}}, metadata !"[[TYPE1:[[:print:]]+]]")
|
||||
pub fn foo2<T>(a: &dyn Trait2<T>) {
|
||||
a.bar();
|
||||
// CHECK-LABEL: define{{.*}}4foo2{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE2:[[:print:]]+]]")
|
||||
}
|
||||
|
||||
pub fn bar2() {
|
||||
let a = Type2;
|
||||
foo2(&a);
|
||||
let b = &a as &dyn Trait2<i32>;
|
||||
b.bar();
|
||||
// CHECK-LABEL: define{{.*}}4bar2{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE2:[[:print:]]+]]")
|
||||
}
|
||||
|
||||
pub fn foo3(a: &dyn Trait3<Type3>) {
|
||||
let b = Type3;
|
||||
a.baz(&b);
|
||||
// CHECK-LABEL: define{{.*}}4foo3{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE3:[[:print:]]+]]")
|
||||
}
|
||||
|
||||
pub fn bar3() {
|
||||
let a = Type3;
|
||||
foo3(&a);
|
||||
let b = &a as &dyn Trait3<Type3>;
|
||||
b.baz(&a);
|
||||
// CHECK-LABEL: define{{.*}}4bar3{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE3:[[:print:]]+]]")
|
||||
}
|
||||
|
||||
// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE1]]"}
|
||||
// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE2]]"}
|
||||
// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE3]]"}
|
||||
|
|
|
@ -30,40 +30,84 @@ trait Freeze { }
|
|||
#[lang="drop_in_place"]
|
||||
fn drop_in_place_fn<T>() { }
|
||||
|
||||
trait Trait1 {
|
||||
pub trait Trait1 {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
struct Type1;
|
||||
pub struct Type1;
|
||||
|
||||
impl Trait1 for Type1 {
|
||||
fn foo(&self) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn foo() {
|
||||
let a = Type1;
|
||||
a.foo();
|
||||
// CHECK-LABEL: define{{.*}}foo{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call <sanitizer_kcfi_emit_type_metadata_trait_objects::Type1 as sanitizer_kcfi_emit_type_metadata_trait_objects::Trait1>::foo
|
||||
pub trait Trait2<T> {
|
||||
fn bar(&self);
|
||||
}
|
||||
|
||||
pub fn bar() {
|
||||
pub struct Type2;
|
||||
|
||||
impl Trait2<i32> for Type2 {
|
||||
fn bar(&self) {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Trait3<T> {
|
||||
fn baz(&self, _: &T);
|
||||
}
|
||||
|
||||
pub struct Type3;
|
||||
|
||||
impl<T, U> Trait3<U> for T {
|
||||
fn baz(&self, _: &U) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn foo1(a: &dyn Trait1) {
|
||||
a.foo();
|
||||
// CHECK-LABEL: define{{.*}}4foo1{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE1:[[:print:]]+]]) ]
|
||||
}
|
||||
|
||||
pub fn bar1() {
|
||||
let a = Type1;
|
||||
let b = &a as &dyn Trait1;
|
||||
b.foo();
|
||||
// CHECK-LABEL: define{{.*}}bar{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call void %0({{\{\}\*|ptr}} align 1 {{%b\.0|%_1}}){{.*}}[ "kcfi"(i32 [[TYPE1:[[:print:]]+]]) ]
|
||||
// CHECK-LABEL: define{{.*}}4bar1{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE1:[[:print:]]+]]) ]
|
||||
}
|
||||
|
||||
pub fn baz() {
|
||||
let a = Type1;
|
||||
let b = &a as &dyn Trait1;
|
||||
a.foo();
|
||||
b.foo();
|
||||
// CHECK-LABEL: define{{.*}}baz{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call <sanitizer_kcfi_emit_type_metadata_trait_objects::Type1 as sanitizer_kcfi_emit_type_metadata_trait_objects::Trait1>::foo
|
||||
// CHECK: call void %0({{\{\}\*|ptr}} align 1 {{%b\.0|%_1}}){{.*}}[ "kcfi"(i32 [[TYPE1:[[:print:]]+]]) ]
|
||||
pub fn foo2<T>(a: &dyn Trait2<T>) {
|
||||
a.bar();
|
||||
// CHECK-LABEL: define{{.*}}4foo2{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE2:[[:print:]]+]]) ]
|
||||
}
|
||||
|
||||
pub fn bar2() {
|
||||
let a = Type2;
|
||||
foo2(&a);
|
||||
let b = &a as &dyn Trait2<i32>;
|
||||
b.bar();
|
||||
// CHECK-LABEL: define{{.*}}4bar2{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE2:[[:print:]]+]]) ]
|
||||
}
|
||||
|
||||
pub fn foo3(a: &dyn Trait3<Type3>) {
|
||||
let b = Type3;
|
||||
a.baz(&b);
|
||||
// CHECK-LABEL: define{{.*}}4foo3{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}, {{\{\}\*|ptr|%Type3\*}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE3:[[:print:]]+]]) ]
|
||||
}
|
||||
|
||||
pub fn bar3() {
|
||||
let a = Type3;
|
||||
foo3(&a);
|
||||
let b = &a as &dyn Trait3<Type3>;
|
||||
b.baz(&a);
|
||||
// CHECK-LABEL: define{{.*}}4bar3{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}, {{\{\}\*|ptr|%Type3\*}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE3:[[:print:]]+]]) ]
|
||||
}
|
||||
|
||||
// CHECK: !{{[0-9]+}} = !{i32 [[TYPE1]]}
|
||||
// CHECK: !{{[0-9]+}} = !{i32 [[TYPE2]]}
|
||||
// CHECK: !{{[0-9]+}} = !{i32 [[TYPE3]]}
|
||||
|
|
Loading…
Add table
Reference in a new issue