Skip to content

Commit

Permalink
CFI: Handle dyn with no principal
Browse files Browse the repository at this point in the history
In user-facing Rust, `dyn` always has at least one predicate following
it. Unfortunately, because we filter out marker traits from receivers at
callsites and `dyn Sync` is, for example, legal, this results in us
having `dyn` types with no predicates on occasion in our alias set
encoding. This patch handles cases where there are no predicates in a
`dyn` type which are relevant to its alias set.

Fixes rust-lang#122998
  • Loading branch information
maurer committed Mar 24, 2024
1 parent 6a92312 commit e0ef3ef
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 2 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/predicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> {
/// have a "trivial" vtable consisting of just the size, alignment,
/// and destructor.
pub fn principal(&self) -> Option<ty::Binder<'tcx, ExistentialTraitRef<'tcx>>> {
self[0]
self.get(0)?
.map_bound(|this| match this {
ExistentialPredicate::Trait(tr) => Some(tr),
_ => None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,11 @@ fn transform_predicates<'tcx>(
ty::ExistentialPredicate::AutoTrait(..) => Some(predicate),
})
.collect();
tcx.mk_poly_existential_predicates(&predicates)
if predicates.len() == 0 {
List::empty()
} else {
tcx.mk_poly_existential_predicates(&predicates)
}
}

/// Transforms args for being encoded and used in the substitution dictionary.
Expand Down
21 changes: 21 additions & 0 deletions tests/ui/sanitizer/cfi-drop-no-principal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Check that dropping a trait object without a principal trait succeeds

//@ needs-sanitizer-cfi
// FIXME(#122848) Remove only-linux once OSX CFI binaries works
//@ only-linux
//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi
//@ compile-flags: -C target-feature=-crt-static -C codegen-units=1 -C opt-level=0
// FIXME(#118761) Should be run-pass once the labels on drop are compatible.
// This test is being landed ahead of that to test that the compiler doesn't ICE while labeling the
// callsite for a drop, but the vtable doesn't have the correct label yet.
//@ build-pass

struct CustomDrop;

impl Drop for CustomDrop {
fn drop(&mut self) {}
}

fn main() {
let _ = Box::new(CustomDrop) as Box<dyn Send>;
}

0 comments on commit e0ef3ef

Please sign in to comment.