1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
// Verifies that type metadata identifiers for trait objects are emitted correctly.
//
//@ needs-sanitizer-cfi
//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Ctarget-feature=-crt-static -Zsanitizer=cfi
#![crate_type = "lib"]
pub trait Trait1 {
fn foo(&self);
}
#[derive(Clone, Copy)]
pub struct Type1;
impl Trait1 for Type1 {
fn foo(&self) {}
}
pub trait Trait2<T> {
fn bar(&self);
}
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 trait Trait4<'a, T> {
type Output: 'a;
fn qux(&self, _: &T) -> Self::Output;
}
pub struct Type4;
impl<'a, T, U> Trait4<'a, U> for T {
type Output = &'a i32;
fn qux(&self, _: &U) -> Self::Output {
&0
}
}
pub trait Trait5<T, const N: usize> {
fn quux(&self, _: &[T; N]);
}
#[derive(Copy, Clone)]
pub struct Type5;
impl<T, U, const N: usize> Trait5<U, N> for T {
fn quux(&self, _: &[U; N]) {}
}
pub fn foo1(a: &dyn Trait1) {
a.foo();
// CHECK-LABEL: define{{.*}}4foo1{{.*}}!type !{{[0-9]+}}
// CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE1:[[:print:]]+]]")
}
pub fn bar1() {
let a = Type1;
let b = &a as &dyn Trait1;
b.foo();
// CHECK-LABEL: define{{.*}}4bar1{{.*}}!type !{{[0-9]+}}
// CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE2:[[:print:]]+]]")
}
pub fn foo2<T>(a: &dyn Trait2<T>) {
a.bar();
// CHECK-LABEL: define{{.*}}4foo2{{.*}}!type !{{[0-9]+}}
// CHECK: call i1 @llvm.type.test(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(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(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(ptr {{%f|%[0-9]}}, metadata !"[[TYPE3:[[:print:]]+]]")
}
pub fn foo4<'a>(a: &dyn Trait4<'a, Type4, Output = &'a i32>) {
let b = Type4;
a.qux(&b);
// CHECK-LABEL: define{{.*}}4foo4{{.*}}!type !{{[0-9]+}}
// CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE4:[[:print:]]+]]")
}
pub fn bar4<'a>() {
let a = Type4;
foo4(&a);
let b = &a as &dyn Trait4<'a, Type4, Output = &'a i32>;
b.qux(&a);
// CHECK-LABEL: define{{.*}}4bar4{{.*}}!type !{{[0-9]+}}
// CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE4:[[:print:]]+]]")
}
pub fn foo5(a: &dyn Trait5<Type5, 32>) {
let b = &[Type5; 32];
a.quux(&b);
// CHECK-LABEL: define{{.*}}4foo5{{.*}}!type !{{[0-9]+}}
// CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE5:[[:print:]]+]]")
}
pub fn bar5() {
let a = &[Type5; 32];
foo5(&a);
let b = &a as &dyn Trait5<Type5, 32>;
b.quux(&a);
// CHECK-LABEL: define{{.*}}4bar5{{.*}}!type !{{[0-9]+}}
// CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE5:[[:print:]]+]]")
}
// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE1]]"}
// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE2]]"}
// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE3]]"}
// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE4]]"}
// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE5]]"}
|