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`
This commit is contained in:
commit
aa01891700
69 changed files with 673 additions and 527 deletions
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue