diff options
| author | Ralf Jung <post@ralfj.de> | 2022-11-06 13:00:09 +0100 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2022-11-06 14:17:10 +0100 |
| commit | 2cef9e3d19087a83fe1431ab8fd915cffd6a22ec (patch) | |
| tree | 2c0d62cb14e977d513c0350ab23b23db34a8a3ef /compiler/rustc_const_eval | |
| parent | 452cf4f7109f58433ac38be7d3da527408571054 (diff) | |
| download | rust-2cef9e3d19087a83fe1431ab8fd915cffd6a22ec.tar.gz rust-2cef9e3d19087a83fe1431ab8fd915cffd6a22ec.zip | |
interpret: support for per-byte provenance
Diffstat (limited to 'compiler/rustc_const_eval')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/intern.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/memory.rs | 35 |
2 files changed, 17 insertions, 22 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 6809a42dc45..458cc6180d5 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -134,7 +134,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_eval: alloc.mutability = Mutability::Not; }; // link the alloc id to the actual allocation - leftover_allocations.extend(alloc.provenance().iter().map(|&(_, alloc_id)| alloc_id)); + leftover_allocations.extend(alloc.provenance().ptrs().iter().map(|&(_, alloc_id)| alloc_id)); let alloc = tcx.intern_const_alloc(alloc); tcx.set_alloc_id_memory(alloc_id, alloc); None @@ -439,7 +439,7 @@ pub fn intern_const_alloc_recursive< } let alloc = tcx.intern_const_alloc(alloc); tcx.set_alloc_id_memory(alloc_id, alloc); - for &(_, alloc_id) in alloc.inner().provenance().iter() { + for &(_, alloc_id) in alloc.inner().provenance().ptrs().iter() { if leftover_allocations.insert(alloc_id) { todo.push(alloc_id); } diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index e5e015c1e18..19e8dd660f0 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -302,8 +302,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { .into()); }; - debug!(?alloc); - if alloc.mutability == Mutability::Not { throw_ub_format!("deallocating immutable allocation {alloc_id:?}"); } @@ -797,7 +795,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // This is a new allocation, add the allocation it points to `todo`. if let Some((_, alloc)) = self.memory.alloc_map.get(id) { todo.extend( - alloc.provenance().values().filter_map(|prov| prov.get_alloc_id()), + alloc.provenance().provenances().filter_map(|prov| prov.get_alloc_id()), ); } } @@ -833,7 +831,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> std::fmt::Debug for DumpAllocs<'a, allocs_to_print: &mut VecDeque<AllocId>, alloc: &Allocation<Prov, Extra>, ) -> std::fmt::Result { - for alloc_id in alloc.provenance().values().filter_map(|prov| prov.get_alloc_id()) { + for alloc_id in alloc.provenance().provenances().filter_map(|prov| prov.get_alloc_id()) + { allocs_to_print.push_back(alloc_id); } write!(fmt, "{}", display_allocation(tcx, alloc)) @@ -962,7 +961,7 @@ impl<'tcx, 'a, Prov: Provenance, Extra> AllocRef<'a, 'tcx, Prov, Extra> { /// Returns whether the allocation has provenance anywhere in the range of the `AllocRef`. pub(crate) fn has_provenance(&self) -> bool { - self.alloc.range_has_provenance(&self.tcx, self.range) + !self.alloc.provenance().range_empty(self.range, &self.tcx) } } @@ -1060,7 +1059,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Source alloc preparations and access hooks. let Some((src_alloc_id, src_offset, src_prov)) = src_parts else { - // Zero-sized *source*, that means dst is also zero-sized and we have nothing to do. + // Zero-sized *source*, that means dest is also zero-sized and we have nothing to do. return Ok(()); }; let src_alloc = self.get_alloc_raw(src_alloc_id)?; @@ -1079,22 +1078,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok(()); }; - // Checks provenance edges on the src, which needs to happen before - // `prepare_provenance_copy`. - if src_alloc.range_has_provenance(&tcx, alloc_range(src_range.start, Size::ZERO)) { - throw_unsup!(PartialPointerCopy(Pointer::new(src_alloc_id, src_range.start))); - } - if src_alloc.range_has_provenance(&tcx, alloc_range(src_range.end(), Size::ZERO)) { - throw_unsup!(PartialPointerCopy(Pointer::new(src_alloc_id, src_range.end()))); - } + // Prepare getting source provenance. let src_bytes = src_alloc.get_bytes_unchecked(src_range).as_ptr(); // raw ptr, so we can also get a ptr to the destination allocation // first copy the provenance to a temporary buffer, because // `get_bytes_mut` will clear the provenance, which is correct, // since we don't want to keep any provenance at the target. - let provenance = - src_alloc.prepare_provenance_copy(self, src_range, dest_offset, num_copies); + // This will also error if copying partial provenance is not supported. + let provenance = src_alloc + .provenance() + .prepare_copy(src_range, dest_offset, num_copies, self) + .map_err(|e| e.to_interp_error(dest_alloc_id))?; // Prepare a copy of the initialization mask. - let compressed = src_alloc.compress_uninit_range(src_range); + let init = src_alloc.compress_uninit_range(src_range); // Destination alloc preparations and access hooks. let (dest_alloc, extra) = self.get_alloc_raw_mut(dest_alloc_id)?; @@ -1111,7 +1106,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { .map_err(|e| e.to_interp_error(dest_alloc_id))? .as_mut_ptr(); - if compressed.no_bytes_init() { + if init.no_bytes_init() { // Fast path: If all bytes are `uninit` then there is nothing to copy. The target range // is marked as uninitialized but we otherwise omit changing the byte representation which may // be arbitrary for uninitialized bytes. @@ -1161,12 +1156,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // now fill in all the "init" data dest_alloc.mark_compressed_init_range( - &compressed, + &init, alloc_range(dest_offset, size), // just a single copy (i.e., not full `dest_range`) num_copies, ); // copy the provenance to the destination - dest_alloc.mark_provenance_range(provenance); + dest_alloc.provenance_apply_copy(provenance); Ok(()) } |
