rust/tests/ui/sanitizer/cfi-supertraits.rs
Matthew Maurer d301f40c84 CFI: Encode Virtual calls as calls through the defining trait
For example, if `trait Foo: Bar`, and we try to call a method from `Bar`
on `dyn Foo`, encode the callsite as passing a `dyn Bar`, not a `dyn
Foo`.
2024-03-29 18:15:41 +00:00

74 lines
1.5 KiB
Rust

#![feature(trait_upcasting)]
// Check that super-traits are callable.
//@ revisions: cfi kcfi
// FIXME(#122848) Remove only-linux once OSX CFI binaries work
//@ only-linux
//@ [cfi] needs-sanitizer-cfi
//@ [kcfi] needs-sanitizer-kcfi
//@ compile-flags: -C target-feature=-crt-static
//@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
//@ [cfi] compile-flags: -Z sanitizer=cfi
//@ [kcfi] compile-flags: -Z sanitizer=kcfi
//@ [kcfi] compile-flags: -C panic=abort -C prefer-dynamic=off
//@ run-pass
trait Parent1 {
type P1;
fn p1(&self) -> Self::P1;
}
trait Parent2 {
type P2;
fn p2(&self) -> Self::P2;
}
trait Child : Parent1 + Parent2 {
type C;
fn c(&self) -> Self::C;
}
struct Foo;
impl Parent1 for Foo {
type P1 = u16;
fn p1(&self) -> Self::P1 {
println!("p1");
1
}
}
impl Parent2 for Foo {
type P2 = u32;
fn p2(&self) -> Self::P2 {
println!("p2");
2
}
}
impl Child for Foo {
type C = u8;
fn c(&self) -> Self::C {
println!("c");
0
}
}
fn main() {
// Child can access its own methods and super methods.
let x = &Foo as &dyn Child<C=u8,P1=u16,P2=u32>;
x.c();
x.p1();
x.p2();
// Parents can be created and access their methods.
let y = &Foo as &dyn Parent1<P1=u16>;
y.p1();
let z = &Foo as &dyn Parent2<P2=u32>;
z.p2();
// Trait upcasting works
let x1 = x as &dyn Parent1<P1=u16>;
x1.p1();
let x2 = x as &dyn Parent2<P2=u32>;
x2.p2();
}