about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-07-22 01:33:49 +0000
committerbors <bors@rust-lang.org>2022-07-22 01:33:49 +0000
commite5e7395cca92765ca56cefe83bce095ad4e6e0c0 (patch)
tree7120901f26b92d513c85d90a77d4494a1f7537da
parent4f118ce1024444988efd9dbd2a2886cb826ce86f (diff)
parent59d223d1ed89f411ebde0e05765e9d7e4f4bf3c7 (diff)
downloadrust-e5e7395cca92765ca56cefe83bce095ad4e6e0c0.tar.gz
rust-e5e7395cca92765ca56cefe83bce095ad4e6e0c0.zip
Auto merge of #99420 - RalfJung:vtable, r=oli-obk
make vtable pointers entirely opaque

This implements the scheme discussed in https://github.com/rust-lang/unsafe-code-guidelines/issues/338: vtable pointers should be considered entirely opaque and not even readable by Rust code, similar to function pointers.

- We have a new kind of `GlobalAlloc` that symbolically refers to a vtable.
- Miri uses that kind of allocation when generating a vtable.
- The codegen backends, upon encountering such an allocation, call `vtable_allocation` to obtain an actually dataful allocation for this vtable.
- We need new intrinsics to obtain the size and align from a vtable (for some `ptr::metadata` APIs), since direct accesses are UB now.

I had to touch quite a bit of code that I am not very familiar with, so some of this might not make much sense...
r? `@oli-obk`
-rw-r--r--src/common.rs5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/common.rs b/src/common.rs
index fc391f53f18..ccb6cbbc2c8 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -201,6 +201,11 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
                         GlobalAlloc::Function(fn_instance) => {
                             self.get_fn_addr(fn_instance)
                         },
+                        GlobalAlloc::VTable(ty, trait_ref) => {
+                            let alloc = self.tcx.global_alloc(self.tcx.vtable_allocation((ty, trait_ref))).unwrap_memory();
+                            let init = const_alloc_to_gcc(self, alloc);
+                            self.static_addr_of(init, alloc.inner().align, None)
+                        }
                         GlobalAlloc::Static(def_id) => {
                             assert!(self.tcx.is_static(def_id));
                             self.get_static(def_id).get_address(None)