check for correct trait in size_and_align_of

This commit is contained in:
Ralf Jung 2024-06-11 07:47:58 +02:00
parent af4d6c74ef
commit d041b7cf30
4 changed files with 10 additions and 7 deletions

View File

@ -765,10 +765,10 @@ pub(super) fn size_and_align_of(
}
Ok(Some((full_size, full_align)))
}
ty::Dynamic(_, _, ty::Dyn) => {
ty::Dynamic(expected_trait, _, ty::Dyn) => {
let vtable = metadata.unwrap_meta().to_pointer(self)?;
// Read size and align from vtable (already checks size).
Ok(Some(self.get_vtable_size_and_align(vtable)?))
Ok(Some(self.get_vtable_size_and_align(vtable, Some(expected_trait))?))
}
ty::Slice(_) | ty::Str => {

View File

@ -432,12 +432,14 @@ pub fn emulate_intrinsic(
sym::vtable_size => {
let ptr = self.read_pointer(&args[0])?;
let (size, _align) = self.get_vtable_size_and_align(ptr)?;
// `None` because we don't know which trait to expect here; any vtable is okay.
let (size, _align) = self.get_vtable_size_and_align(ptr, None)?;
self.write_scalar(Scalar::from_target_usize(size.bytes(), self), dest)?;
}
sym::vtable_align => {
let ptr = self.read_pointer(&args[0])?;
let (_size, align) = self.get_vtable_size_and_align(ptr)?;
// `None` because we don't know which trait to expect here; any vtable is okay.
let (_size, align) = self.get_vtable_size_and_align(ptr, None)?;
self.write_scalar(Scalar::from_target_usize(align.bytes(), self), dest)?;
}

View File

@ -36,8 +36,9 @@ pub fn get_vtable_ptr(
pub fn get_vtable_size_and_align(
&self,
vtable: Pointer<Option<M::Provenance>>,
expected_trait: Option<&'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>>,
) -> InterpResult<'tcx, (Size, Align)> {
let ty = self.get_ptr_vtable_ty(vtable, None)?;
let ty = self.get_ptr_vtable_ty(vtable, expected_trait)?;
let layout = self.layout_of(ty)?;
assert!(layout.is_sized(), "there are no vtables for unsized types");
Ok((layout.size, layout.align.abi))

View File

@ -1,5 +1,5 @@
// Validation stops this too early.
//@compile-flags: -Zmiri-disable-validation
// Validation and SB stop this too early.
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
trait T1 {
#[allow(dead_code)]