diff options
| author | bors <bors@rust-lang.org> | 2022-07-22 01:33:49 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-07-22 01:33:49 +0000 |
| commit | aa0189170057a6b56f445f05b9840caf6f260212 (patch) | |
| tree | 44b90133d775da8a57ad4a5d8a5464e1329125c2 /compiler/rustc_codegen_ssa | |
| parent | 31b9b012bbced0c47a0ff5e4453cdc2e91e668b2 (diff) | |
| parent | d46dfa25d46be353a0cda39373e0319eb4f3ec69 (diff) | |
| download | rust-aa0189170057a6b56f445f05b9840caf6f260212.tar.gz rust-aa0189170057a6b56f445f05b9840caf6f260212.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`
Diffstat (limited to 'compiler/rustc_codegen_ssa')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/base.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/meth.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 20 |
3 files changed, 22 insertions, 4 deletions
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 7def30af2b3..d95194e320b 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -171,7 +171,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( ); let new_vptr = bx.load(ptr_ty, gep, ptr_align); bx.nonnull_metadata(new_vptr); - // Vtable loads are invariant. + // VTable loads are invariant. bx.set_invariant_load(new_vptr); new_vptr } else { diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index df42d804566..27d791d90a5 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -39,7 +39,7 @@ impl<'a, 'tcx> VirtualIndex { let gep = bx.inbounds_gep(llty, llvtable, &[bx.const_usize(self.0)]); let ptr = bx.load(llty, gep, ptr_align); bx.nonnull_metadata(ptr); - // Vtable loads are invariant. + // VTable loads are invariant. bx.set_invariant_load(ptr); ptr } @@ -58,7 +58,7 @@ impl<'a, 'tcx> VirtualIndex { let usize_align = bx.tcx().data_layout.pointer_align.abi; let gep = bx.inbounds_gep(llty, llvtable, &[bx.const_usize(self.0)]); let ptr = bx.load(llty, gep, usize_align); - // Vtable loads are invariant. + // VTable loads are invariant. bx.set_invariant_load(ptr); ptr } diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 645afae30d8..94ac71a4dd2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -3,12 +3,16 @@ use super::place::PlaceRef; use super::FunctionCx; use crate::common::{span_invalid_monomorphization_error, IntPredicate}; use crate::glue; +use crate::meth; use crate::traits::*; use crate::MemFlags; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::{sym, Span}; -use rustc_target::abi::call::{FnAbi, PassMode}; +use rustc_target::abi::{ + call::{FnAbi, PassMode}, + WrappingRange, +}; fn copy_intrinsic<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, @@ -102,6 +106,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.const_usize(bx.layout_of(tp_ty).align.abi.bytes()) } } + sym::vtable_size | sym::vtable_align => { + let vtable = args[0].immediate(); + let idx = match name { + sym::vtable_size => ty::COMMON_VTABLE_ENTRIES_SIZE, + sym::vtable_align => ty::COMMON_VTABLE_ENTRIES_ALIGN, + _ => bug!(), + }; + let value = meth::VirtualIndex::from_index(idx).get_usize(bx, vtable); + if name == sym::vtable_align { + // Alignment is always nonzero. + bx.range_metadata(value, WrappingRange { start: 1, end: !0 }); + }; + value + } sym::pref_align_of | sym::needs_drop | sym::type_id |
