about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2025-09-08 10:40:18 +0200
committerRalf Jung <post@ralfj.de>2025-09-08 13:22:52 +0200
commitaed0ed4c93d661fc7b66dc4a39690948476e8a4a (patch)
treedefedf24675aa706b949f66950d41ac2ffa1fbc0 /compiler
parentebdf2abea4b46fcbba959eee1207c979c77dc95c (diff)
downloadrust-aed0ed4c93d661fc7b66dc4a39690948476e8a4a.tar.gz
rust-aed0ed4c93d661fc7b66dc4a39690948476e8a4a.zip
const-eval: disable pointer fragment support
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs6
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs5
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs16
3 files changed, 23 insertions, 4 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 2c1e5087e1c..6ec85648d6d 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -1501,8 +1501,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         // `get_bytes_mut` will clear the provenance, which is correct,
         // since we don't want to keep any provenance at the target.
         // 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);
+        let provenance = src_alloc
+            .provenance()
+            .prepare_copy(src_range, dest_offset, num_copies, self)
+            .map_err(|e| e.to_interp_error(src_alloc_id))?;
         // Prepare a copy of the initialization mask.
         let init = src_alloc.init_mask().prepare_copy(src_range);
 
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index 2ea92a39d48..67962813ae4 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -724,6 +724,11 @@ impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
             }
             // If we get here, we have to check per-byte provenance, and join them together.
             let prov = 'prov: {
+                if !Prov::OFFSET_IS_ADDR {
+                    // FIXME(#146291): We need to ensure that we don't mix different pointers with
+                    // the same provenance.
+                    return Err(AllocError::ReadPartialPointer(range.start));
+                }
                 // Initialize with first fragment. Must have index 0.
                 let Some((mut joint_prov, 0)) = self.provenance.get_byte(range.start, cx) else {
                     break 'prov None;
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs
index dbbd95408c8..720e58d7aa0 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs
@@ -11,6 +11,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use tracing::trace;
 
 use super::{AllocRange, CtfeProvenance, Provenance, alloc_range};
+use crate::mir::interpret::{AllocError, AllocResult};
 
 /// Stores the provenance information of pointers stored in memory.
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
@@ -137,6 +138,11 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
         let Some(bytes) = self.bytes.as_deref_mut() else {
             return true;
         };
+        if !Prov::OFFSET_IS_ADDR {
+            // FIXME(#146291): We need to ensure that we don't mix different pointers with
+            // the same provenance.
+            return false;
+        }
         let ptr_size = cx.data_layout().pointer_size();
         while let Some((offset, (prov, _))) = bytes.iter().next().copied() {
             // Check if this fragment starts a pointer.
@@ -285,7 +291,7 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
         dest: Size,
         count: u64,
         cx: &impl HasDataLayout,
-    ) -> ProvenanceCopy<Prov> {
+    ) -> AllocResult<ProvenanceCopy<Prov>> {
         let shift_offset = move |idx, offset| {
             // compute offset for current repetition
             let dest_offset = dest + src.size * idx; // `Size` operations
@@ -363,6 +369,12 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
             }
             trace!("byte provenances: {bytes:?}");
 
+            if !bytes.is_empty() && !Prov::OFFSET_IS_ADDR {
+                // FIXME(#146291): We need to ensure that we don't mix different pointers with
+                // the same provenance.
+                return Err(AllocError::ReadPartialPointer(src.start));
+            }
+
             // And again a buffer for the new list on the target side.
             let mut dest_bytes = Vec::with_capacity(bytes.len() * (count as usize));
             for i in 0..count {
@@ -373,7 +385,7 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
             dest_bytes_box = Some(dest_bytes.into_boxed_slice());
         }
 
-        ProvenanceCopy { dest_ptrs: dest_ptrs_box, dest_bytes: dest_bytes_box }
+        Ok(ProvenanceCopy { dest_ptrs: dest_ptrs_box, dest_bytes: dest_bytes_box })
     }
 
     /// Applies a provenance copy.