Skip to content

Commit

Permalink
Move provenance checks out of interning method.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjgillot committed Oct 10, 2023
1 parent e163486 commit 0bc44f7
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 17 deletions.
14 changes: 2 additions & 12 deletions compiler/rustc_const_eval/src/interpret/intern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ pub fn intern_const_alloc_recursive<
Ok(())
}

/// Intern `ret`, checking it references no other allocation.
/// Intern `ret`. This function assumes that `ret` references no other allocation.
#[instrument(level = "debug", skip(ecx))]
pub fn intern_const_alloc_for_constprop<
'mir,
Expand All @@ -461,17 +461,7 @@ pub fn intern_const_alloc_for_constprop<
ecx: &mut InterpCx<'mir, 'tcx, M>,
ret: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, ()> {
let Some((size, align)) = ecx.size_and_align_of_mplace(ret)? else {
throw_inval!(ConstPropNonsense)
};

let alloc_ref = ecx.get_ptr_alloc(ret.ptr(), size, align)?.unwrap();
// Do not try interning a value that contains provenance.
if alloc_ref.has_provenance() {
throw_inval!(ConstPropNonsense)
}

// remove allocation
// Move allocation to `tcx`.
let alloc_id = ret.ptr().provenance.unwrap();
let Some((_, mut alloc)) = ecx.memory.alloc_map.remove(&alloc_id) else {
// Pointer not found in local memory map. It is either a pointer to the global
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,7 @@ impl<'tcx, 'a, Prov: Provenance, Extra, Bytes: AllocBytes> AllocRef<'a, 'tcx, Pr
}

/// Returns whether the allocation has provenance anywhere in the range of the `AllocRef`.
pub(crate) fn has_provenance(&self) -> bool {
pub fn has_provenance(&self) -> bool {
!self.alloc.provenance().range_empty(self.range, &self.tcx)
}
}
Expand Down
21 changes: 17 additions & 4 deletions compiler/rustc_mir_transform/src/gvn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,7 @@ fn op_to_prop_const<'tcx>(
// If this constant has scalar ABI, return it as a `ConstValue::Scalar`.
if let Abi::Scalar(abi::Scalar::Initialized { .. }) = op.layout.abi
&& let Ok(scalar) = ecx.read_scalar(op)
&& scalar.try_to_int().is_ok()
{
return Some(ConstValue::Scalar(scalar));
}
Expand All @@ -833,6 +834,14 @@ fn op_to_prop_const<'tcx>(
if let Either::Left(mplace) = op.as_mplace_or_imm()
&& let MemPlaceMeta::None = mplace.meta()
{
let (size, align) = ecx.size_and_align_of_mplace(&mplace).ok()??;

let alloc_ref = ecx.get_ptr_alloc(mplace.ptr(), size, align).ok()??;
// Do not try interning a value that contains provenance.
if alloc_ref.has_provenance() {
return None;
}

intern_const_alloc_for_constprop(ecx, &mplace).ok()?;
let pointer = mplace.ptr().into_pointer_or_addr().ok()?;
let (alloc_id, offset) = pointer.into_parts();
Expand All @@ -846,7 +855,13 @@ fn op_to_prop_const<'tcx>(
// Everything failed: create a new allocation to hold the data.
let alloc_id =
ecx.intern_with_temp_alloc(op.layout, |ecx, dest| ecx.copy_op(op, dest, false)).ok()?;
Some(ConstValue::Indirect { alloc_id, offset: Size::ZERO })
let value = ConstValue::Indirect { alloc_id, offset: Size::ZERO };

if !value.has_provenance(*ecx.tcx, op.layout.size) {
return Some(value);
}

None
}

impl<'tcx> VnState<'_, 'tcx> {
Expand Down Expand Up @@ -898,9 +913,7 @@ impl<'tcx> VnState<'_, 'tcx> {

// Check that we do not leak a pointer.
// Those pointers may lose part of their identity in codegen.
if value.has_provenance(self.tcx, op.layout.size) {
return None;
}
assert!(!value.has_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_ })
Expand Down

0 comments on commit 0bc44f7

Please sign in to comment.