]> git.proxmox.com Git - rustc.git/blob - tests/ui/consts/const-eval/ub-incorrect-vtable.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / tests / ui / consts / const-eval / ub-incorrect-vtable.rs
1 // This test contains code with incorrect vtables in a const context:
2 // - from issue 86132: a trait object with invalid alignment caused an ICE in const eval, and now
3 // triggers an error
4 // - a similar test that triggers a previously-untested const UB error: emitted close to the above
5 // error, it checks the correctness of the size
6 //
7 // As is, this code will only hard error when the constants are used, and the errors are emitted via
8 // the `#[allow]`-able `const_err` lint. However, if the transparent wrapper technique to prevent
9 // reborrows is used -- from `ub-wide-ptr.rs` -- these two errors reach validation and would trigger
10 // ICEs as tracked by #86193. So we also use the transparent wrapper to verify proper validation
11 // errors are emitted instead of ICEs.
12
13 // stderr-per-bitwidth
14 // normalize-stderr-test "alloc\d+" -> "allocN"
15
16 trait Trait {}
17
18 const INVALID_VTABLE_ALIGNMENT: &dyn Trait =
19 unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) };
20 //~^ ERROR evaluation of constant value failed
21 //~| does not point to a vtable
22
23 const INVALID_VTABLE_SIZE: &dyn Trait =
24 unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) };
25 //~^ ERROR evaluation of constant value failed
26 //~| does not point to a vtable
27
28 #[repr(transparent)]
29 struct W<T>(T);
30
31 fn drop_me(_: *mut usize) {}
32
33 const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> =
34 unsafe { std::mem::transmute((&92u8, &(drop_me as fn(*mut usize), 1usize, 1000usize))) };
35 //~^^ ERROR it is undefined behavior to use this value
36 //~| expected a vtable pointer
37
38 const INVALID_VTABLE_SIZE_UB: W<&dyn Trait> =
39 unsafe { std::mem::transmute((&92u8, &(drop_me as fn(*mut usize), usize::MAX, 1usize))) };
40 //~^^ ERROR it is undefined behavior to use this value
41 //~| expected a vtable pointer
42
43 // Even if the vtable has a fn ptr and a reasonable size+align, it still does not work.
44 const INVALID_VTABLE_UB: W<&dyn Trait> =
45 unsafe { std::mem::transmute((&92u8, &(drop_me as fn(*mut usize), 1usize, 1usize))) };
46 //~^^ ERROR it is undefined behavior to use this value
47 //~| expected a vtable pointer
48
49 // Trying to access the data in a vtable does not work, either.
50
51 #[derive(Copy, Clone)]
52 struct Wide<'a>(&'a Foo, &'static VTable);
53
54 struct VTable {
55 drop: Option<for<'a> fn(&'a mut Foo)>,
56 size: usize,
57 align: usize,
58 bar: for<'a> fn(&'a Foo) -> u32,
59 }
60
61 trait Bar {
62 fn bar(&self) -> u32;
63 }
64
65 struct Foo {
66 foo: u32,
67 bar: bool,
68 }
69
70 impl Bar for Foo {
71 fn bar(&self) -> u32 {
72 self.foo
73 }
74 }
75
76 impl Drop for Foo {
77 fn drop(&mut self) {
78 assert!(!self.bar);
79 self.bar = true;
80 println!("dropping Foo");
81 }
82 }
83
84 #[repr(C)]
85 union Transmute<T: Copy, U: Copy> {
86 t: T,
87 u: U,
88 }
89
90 const FOO: &dyn Bar = &Foo { foo: 128, bar: false };
91 const G: Wide = unsafe { Transmute { t: FOO }.u };
92 //~^ ERROR it is undefined behavior to use this value
93 //~| encountered a dangling reference
94 // (it is dangling because vtables do not contain memory that can be dereferenced)
95
96 fn main() {}