From d041b7cf30bb5b5236cd9148cde7a3017ed28679 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 11 Jun 2024 07:47:58 +0200 Subject: [PATCH] check for correct trait in size_and_align_of --- compiler/rustc_const_eval/src/interpret/eval_context.rs | 4 ++-- compiler/rustc_const_eval/src/interpret/intrinsics.rs | 6 ++++-- compiler/rustc_const_eval/src/interpret/traits.rs | 3 ++- src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 7c2100fcbe3..e28cc05cc2a 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -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 => { diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 18b76443cd9..497ae500144 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -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)?; } diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs index 1df9f5f7b2a..44e7244a513 100644 --- a/compiler/rustc_const_eval/src/interpret/traits.rs +++ b/compiler/rustc_const_eval/src/interpret/traits.rs @@ -36,8 +36,9 @@ pub fn get_vtable_ptr( pub fn get_vtable_size_and_align( &self, vtable: Pointer>, + expected_trait: Option<&'tcx ty::List>>, ) -> 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)) diff --git a/src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs b/src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs index f71df9a1c90..982d57b7372 100644 --- a/src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs +++ b/src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs @@ -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)]