about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2021-07-16 11:16:32 +0200
committerRalf Jung <post@ralfj.de>2021-07-16 13:16:09 +0200
commita5299fb6889d6eabba2b4b1a7d7e9decd49182ee (patch)
treee1ac1177e7555519b7bc366d7588c9e7febb3291
parent7c720ce6121dd878b25f8e6a645a07563e5a4b01 (diff)
downloadrust-a5299fb6889d6eabba2b4b1a7d7e9decd49182ee.tar.gz
rust-a5299fb6889d6eabba2b4b1a7d7e9decd49182ee.zip
add some comments regarding the two major quirks of our memory model
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs9
1 files changed, 8 insertions, 1 deletions
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index 56b8f9b928f..bbf792edcde 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -285,6 +285,9 @@ impl<Tag: Copy, Extra> Allocation<Tag, Extra> {
     /// A raw pointer variant of `get_bytes_mut` that avoids invalidating existing aliases into this memory.
     pub fn get_bytes_mut_ptr(&mut self, cx: &impl HasDataLayout, range: AllocRange) -> *mut [u8] {
         self.mark_init(range, true);
+        // This also clears relocations that just overlap with the written range. So writing to some
+        // byte can de-initialize its neighbors! See
+        // <https://github.com/rust-lang/rust/issues/87184> for details.
         self.clear_relocations(cx, range);
 
         assert!(range.end().bytes_usize() <= self.bytes.len()); // need to do our own bounds-check
@@ -327,7 +330,11 @@ impl<Tag: Copy, Extra> Allocation<Tag, Extra> {
         cx: &impl HasDataLayout,
         range: AllocRange,
     ) -> AllocResult<ScalarMaybeUninit<Tag>> {
-        // `get_bytes_unchecked` tests relocation edges.
+        // `get_bytes_with_uninit_and_ptr` tests relocation edges.
+        // We deliberately error when loading data that partially has provenance, or partially
+        // initialized data (that's the check below), into a scalar. The LLVM semantics of this are
+        // unclear so we are conservative. See <https://github.com/rust-lang/rust/issues/69488> for
+        // further discussion.
         let bytes = self.get_bytes_with_uninit_and_ptr(cx, range)?;
         // Uninit check happens *after* we established that the alignment is correct.
         // We must not return `Ok()` for unaligned pointers!