Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6464e5b

Browse files
Rollup merge of rust-lang#123075 - rcvalle:rust-cfi-fix-drop-drop-in-place, r=compiler-errors
CFI: Fix drop and drop_in_place Fix drop and drop_in_place by transforming self of drop and drop_in_place methods into a Drop trait objects. This was split off from rust-lang#116404. cc `@compiler-errors` `@workingjubilee`
2 parents a9ed9fb + 0b86081 commit 6464e5b

File tree

4 files changed

+79
-2
lines changed

4 files changed

+79
-2
lines changed

‎compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs‎

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,8 +1112,36 @@ pub fn typeid_for_instance<'tcx>(
11121112
mut instance: Instance<'tcx>,
11131113
options: TypeIdOptions,
11141114
) -> String {
1115-
if matches!(instance.def, ty::InstanceDef::Virtual(..)) {
1116-
instance.args = strip_receiver_auto(tcx, instance.args)
1115+
if (matches!(instance.def, ty::InstanceDef::Virtual(..))
1116+
&& Some(instance.def_id()) == tcx.lang_items().drop_in_place_fn())
1117+
|| matches!(instance.def, ty::InstanceDef::DropGlue(..))
1118+
{
1119+
// Adjust the type ids of DropGlues
1120+
//
1121+
// DropGlues may have indirect calls to one or more given types drop function. Rust allows
1122+
// for types to be erased to any trait object and retains the drop function for the original
1123+
// type, which means at the indirect call sites in DropGlues, when typeid_for_fnabi is
1124+
// called a second time, it only has information after type erasure and it could be a call
1125+
// on any arbitrary trait object. Normalize them to a synthesized Drop trait object, both on
1126+
// declaration/definition, and during code generation at call sites so they have the same
1127+
// type id and match.
1128+
//
1129+
// FIXME(rcvalle): This allows a drop call on any trait object to call the drop function of
1130+
// any other type.
1131+
//
1132+
let def_id = tcx
1133+
.lang_items()
1134+
.drop_trait()
1135+
.unwrap_or_else(|| bug!("typeid_for_instance: couldn't get drop_trait lang item"));
1136+
let predicate = ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef {
1137+
def_id: def_id,
1138+
args: List::empty(),
1139+
});
1140+
let predicates = tcx.mk_poly_existential_predicates(&[ty::Binder::dummy(predicate)]);
1141+
let self_ty = Ty::new_dynamic(tcx, predicates, tcx.lifetimes.re_erased, ty::Dyn);
1142+
instance.args = tcx.mk_args_trait(self_ty, List::empty());
1143+
} else if matches!(instance.def, ty::InstanceDef::Virtual(..)) {
1144+
instance.args = strip_receiver_auto(tcx, instance.args);
11171145
}
11181146

11191147
if let Some(impl_id) = tcx.impl_of_method(instance.def_id())
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Verifies that type metadata identifiers for drop functions are emitted correctly.
2+
//
3+
//@ needs-sanitizer-cfi
4+
//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
5+
6+
#![crate_type="lib"]
7+
8+
// CHECK-LABEL: define{{.*}}4core3ptr47drop_in_place$LT$dyn$u20$core..marker..Send$GT$
9+
// CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
10+
// CHECK: call i1 @llvm.type.test(ptr {{%.+}}, metadata !"_ZTSFvPu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops4drop4Dropu6regionEE")
11+
12+
struct EmptyDrop;
13+
// CHECK: define{{.*}}4core3ptr{{[0-9]+}}drop_in_place$LT${{.*}}EmptyDrop$GT${{.*}}!type ![[TYPE1]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
14+
15+
struct NonEmptyDrop;
16+
17+
impl Drop for NonEmptyDrop {
18+
fn drop(&mut self) {}
19+
// CHECK: define{{.*}}4core3ptr{{[0-9]+}}drop_in_place$LT${{.*}}NonEmptyDrop$GT${{.*}}!type ![[TYPE1]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
20+
}
21+
22+
pub fn foo() {
23+
let _ = Box::new(EmptyDrop) as Box<dyn Send>;
24+
let _ = Box::new(NonEmptyDrop) as Box<dyn Send>;
25+
}
26+
27+
// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvPu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops4drop4Dropu6regionEE"}

‎tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b
2929
trait Freeze { }
3030
#[lang="drop_in_place"]
3131
fn drop_in_place_fn<T>() { }
32+
#[lang="drop"]
33+
trait Drop { fn drop(&mut self); }
3234

3335
pub trait Trait1 {
3436
fn foo(&self);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Verifies that drops can be called on arbitrary trait objects.
2+
//
3+
// FIXME(#122848): Remove only-linux when fixed.
4+
//@ only-linux
5+
//@ needs-sanitizer-cfi
6+
//@ compile-flags: -Clto -Copt-level=0 -Cprefer-dynamic=off -Ctarget-feature=-crt-static -Zsanitizer=cfi
7+
//@ run-pass
8+
9+
struct EmptyDrop;
10+
11+
struct NonEmptyDrop;
12+
13+
impl Drop for NonEmptyDrop {
14+
fn drop(&mut self) {}
15+
}
16+
17+
fn main() {
18+
let _ = Box::new(EmptyDrop) as Box<dyn Send>;
19+
let _ = Box::new(NonEmptyDrop) as Box<dyn Send>;
20+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /