about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2023-10-23 18:27:54 +0000
committerCamille GILLOT <gillot.camille@gmail.com>2023-10-25 17:59:30 +0000
commit72f0e0e79535246c31b0b1e992f9b0ef8a072dc4 (patch)
tree6ba06365752510fda6e63be5327f8b5cc43096a2
parenteda1928baa868495cd3481358390f8a4e286a659 (diff)
downloadrust-72f0e0e79535246c31b0b1e992f9b0ef8a072dc4.tar.gz
rust-72f0e0e79535246c31b0b1e992f9b0ef8a072dc4.zip
Rename has_provance and tweaks comments.
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs5
-rw-r--r--compiler/rustc_middle/src/mir/consts.rs19
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs12
3 files changed, 24 insertions, 12 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index 23d6d321947..3d90e95c09c 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -474,9 +474,12 @@ pub fn intern_const_alloc_for_constprop<
 
     alloc.mutability = Mutability::Not;
 
-    // link the alloc id to the actual allocation
+    // We are not doing recursive interning, so we don't currently support provenance.
+    // (If this assertion ever triggers, we should just implement a
+    // proper recursive interning loop.)
     assert!(alloc.provenance().ptrs().is_empty());
 
+    // Link the alloc id to the actual allocation
     let alloc = ecx.tcx.mk_const_alloc(alloc);
     ecx.tcx.set_alloc_id_memory(alloc_id, alloc);
 
diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs
index 88d4a37f210..9ddf3903d04 100644
--- a/compiler/rustc_middle/src/mir/consts.rs
+++ b/compiler/rustc_middle/src/mir/consts.rs
@@ -173,16 +173,19 @@ impl<'tcx> ConstValue<'tcx> {
         Some(data.inner().inspect_with_uninit_and_ptr_outside_interpreter(start..end))
     }
 
-    pub fn has_provenance(&self, tcx: TyCtxt<'tcx>, size: Size) -> bool {
-        let (alloc, start, end) = match *self {
+    /// Check if a constant may contain provenance information. This is used by MIR opts.
+    pub fn may_have_provenance(&self, tcx: TyCtxt<'tcx>, size: Size) -> bool {
+        match *self {
             ConstValue::ZeroSized | ConstValue::Scalar(Scalar::Int(_)) => return false,
             ConstValue::Scalar(Scalar::Ptr(..)) => return true,
-            ConstValue::Slice { data, meta } => (data, Size::ZERO, Size::from_bytes(meta)),
-            ConstValue::Indirect { alloc_id, offset } => {
-                (tcx.global_alloc(alloc_id).unwrap_memory(), offset, offset + size)
-            }
-        };
-        !alloc.inner().provenance().range_empty(super::AllocRange::from(start..end), &tcx)
+            ConstValue::Slice { data, meta: _ } => !data.inner().provenance().ptrs().is_empty(),
+            ConstValue::Indirect { alloc_id, offset } => !tcx
+                .global_alloc(alloc_id)
+                .unwrap_memory()
+                .inner()
+                .provenance()
+                .range_empty(super::AllocRange::from(offset..offset + size), &tcx),
+        }
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index cfa315fe61a..3f30f399588 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -910,11 +910,13 @@ fn op_to_prop_const<'tcx>(
         return Some(ConstValue::Scalar(scalar));
     }
 
-    // If this constant is a projection of another, we can return it directly.
+    // If this constant is already represented as an `Allocation`,
+    // try putting it into global memory to return it.
     if let Either::Left(mplace) = op.as_mplace_or_imm() {
         let (size, _align) = ecx.size_and_align_of_mplace(&mplace).ok()??;
 
         // Do not try interning a value that contains provenance.
+        // Due to https://github.com/rust-lang/rust/issues/79738, doing so could lead to bugs.
         let alloc_ref = ecx.get_ptr_alloc(mplace.ptr(), size).ok()??;
         if alloc_ref.has_provenance() {
             return None;
@@ -935,7 +937,10 @@ fn op_to_prop_const<'tcx>(
         ecx.intern_with_temp_alloc(op.layout, |ecx, dest| ecx.copy_op(op, dest, false)).ok()?;
     let value = ConstValue::Indirect { alloc_id, offset: Size::ZERO };
 
-    if !value.has_provenance(*ecx.tcx, op.layout.size) {
+    // Check that we do not leak a pointer.
+    // Those pointers may lose part of their identity in codegen.
+    // See https://github.com/rust-lang/rust/issues/79738.
+    if !value.may_have_provenance(*ecx.tcx, op.layout.size) {
         return Some(value);
     }
 
@@ -964,7 +969,8 @@ impl<'tcx> VnState<'_, 'tcx> {
 
         // Check that we do not leak a pointer.
         // Those pointers may lose part of their identity in codegen.
-        assert!(!value.has_provenance(self.tcx, op.layout.size));
+        // See https://github.com/rust-lang/rust/issues/79738.
+        assert!(!value.may_have_provenance(self.tcx, op.layout.size));
 
         let const_ = Const::Val(value, op.layout.ty);
         Some(ConstOperand { span: rustc_span::DUMMY_SP, user_ty: None, const_ })