diff options
| author | bors <bors@rust-lang.org> | 2024-09-10 02:18:51 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-09-10 02:18:51 +0000 |
| commit | 304b7f801bab31233680879ca4fb6eb294706a59 (patch) | |
| tree | 055d4e61a81f90059600a3aeca1b8526eae394e6 /compiler/rustc_const_eval/src/interpret/visitor.rs | |
| parent | 712463de61c65033a6f333f0a14fbb65e34efc50 (diff) | |
| parent | 0a70924c2160c8f93a446328e207a1983e62596a (diff) | |
| download | rust-304b7f801bab31233680879ca4fb6eb294706a59.tar.gz rust-304b7f801bab31233680879ca4fb6eb294706a59.zip | |
Auto merge of #129778 - RalfJung:interp-lossy-typed-copy, r=saethlin
interpret: make typed copies lossy wrt provenance and padding A "typed copy" in Rust can be a lossy process: when copying at type `usize` (or any other non-pointer type), if the original memory had any provenance, that provenance is lost. When copying at pointer type, if the original memory had partial provenance (i.e., not the same provenance for all bytes), that provenance is lost. When copying any type with padding, the contents of padding are lost. This PR equips our validity-checking pass with the ability to reset provenance and padding according to those rules. Can be reviewed commit-by-commit. The first three commits are just preparation without any functional change. Fixes https://github.com/rust-lang/miri/issues/845 Fixes https://github.com/rust-lang/miri/issues/2182
Diffstat (limited to 'compiler/rustc_const_eval/src/interpret/visitor.rs')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/visitor.rs | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index b02f12e3c7f..d8af67bd0e7 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -5,6 +5,7 @@ use std::num::NonZero; use rustc_index::IndexVec; use rustc_middle::mir::interpret::InterpResult; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty}; use rustc_target::abi::{FieldIdx, FieldsShape, VariantIdx, Variants}; use tracing::trace; @@ -82,6 +83,7 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { self.visit_value(new_val) } + /// Traversal logic; should not be overloaded. fn walk_value(&mut self, v: &Self::V) -> InterpResult<'tcx> { let ty = v.layout().ty; trace!("walk_value: type: {ty}"); @@ -104,6 +106,17 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { // DynStar types. Very different from a dyn type (but strangely part of the // same variant in `TyKind`): These are pairs where the 2nd component is the // vtable, and the first component is the data (which must be ptr-sized). + + // First make sure the vtable can be read at its type. + // The type of this vtable is fake, it claims to be a reference to some actual memory but that isn't true. + // So we transmute it to a raw pointer. + let raw_ptr_ty = Ty::new_mut_ptr(*self.ecx().tcx, self.ecx().tcx.types.unit); + let raw_ptr_ty = self.ecx().layout_of(raw_ptr_ty)?; + let vtable_field = + self.ecx().project_field(v, 1)?.transmute(raw_ptr_ty, self.ecx())?; + self.visit_field(v, 1, &vtable_field)?; + + // Then unpack the first field, and continue. let data = self.ecx().unpack_dyn_star(v, data)?; return self.visit_field(v, 0, &data); } |
