Rename has_provance and tweaks comments.
This commit is contained in:
parent
eda1928baa
commit
72f0e0e795
3 changed files with 24 additions and 12 deletions
|
@ -474,9 +474,12 @@ pub fn intern_const_alloc_for_constprop<
|
||||||
|
|
||||||
alloc.mutability = Mutability::Not;
|
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());
|
assert!(alloc.provenance().ptrs().is_empty());
|
||||||
|
|
||||||
|
// Link the alloc id to the actual allocation
|
||||||
let alloc = ecx.tcx.mk_const_alloc(alloc);
|
let alloc = ecx.tcx.mk_const_alloc(alloc);
|
||||||
ecx.tcx.set_alloc_id_memory(alloc_id, alloc);
|
ecx.tcx.set_alloc_id_memory(alloc_id, alloc);
|
||||||
|
|
||||||
|
|
|
@ -173,16 +173,19 @@ impl<'tcx> ConstValue<'tcx> {
|
||||||
Some(data.inner().inspect_with_uninit_and_ptr_outside_interpreter(start..end))
|
Some(data.inner().inspect_with_uninit_and_ptr_outside_interpreter(start..end))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_provenance(&self, tcx: TyCtxt<'tcx>, size: Size) -> bool {
|
/// Check if a constant may contain provenance information. This is used by MIR opts.
|
||||||
let (alloc, start, end) = match *self {
|
pub fn may_have_provenance(&self, tcx: TyCtxt<'tcx>, size: Size) -> bool {
|
||||||
|
match *self {
|
||||||
ConstValue::ZeroSized | ConstValue::Scalar(Scalar::Int(_)) => return false,
|
ConstValue::ZeroSized | ConstValue::Scalar(Scalar::Int(_)) => return false,
|
||||||
ConstValue::Scalar(Scalar::Ptr(..)) => return true,
|
ConstValue::Scalar(Scalar::Ptr(..)) => return true,
|
||||||
ConstValue::Slice { data, meta } => (data, Size::ZERO, Size::from_bytes(meta)),
|
ConstValue::Slice { data, meta: _ } => !data.inner().provenance().ptrs().is_empty(),
|
||||||
ConstValue::Indirect { alloc_id, offset } => {
|
ConstValue::Indirect { alloc_id, offset } => !tcx
|
||||||
(tcx.global_alloc(alloc_id).unwrap_memory(), offset, offset + size)
|
.global_alloc(alloc_id)
|
||||||
}
|
.unwrap_memory()
|
||||||
};
|
.inner()
|
||||||
!alloc.inner().provenance().range_empty(super::AllocRange::from(start..end), &tcx)
|
.provenance()
|
||||||
|
.range_empty(super::AllocRange::from(offset..offset + size), &tcx),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -910,11 +910,13 @@ fn op_to_prop_const<'tcx>(
|
||||||
return Some(ConstValue::Scalar(scalar));
|
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() {
|
if let Either::Left(mplace) = op.as_mplace_or_imm() {
|
||||||
let (size, _align) = ecx.size_and_align_of_mplace(&mplace).ok()??;
|
let (size, _align) = ecx.size_and_align_of_mplace(&mplace).ok()??;
|
||||||
|
|
||||||
// Do not try interning a value that contains provenance.
|
// 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()??;
|
let alloc_ref = ecx.get_ptr_alloc(mplace.ptr(), size).ok()??;
|
||||||
if alloc_ref.has_provenance() {
|
if alloc_ref.has_provenance() {
|
||||||
return None;
|
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()?;
|
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 };
|
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);
|
return Some(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -964,7 +969,8 @@ impl<'tcx> VnState<'_, 'tcx> {
|
||||||
|
|
||||||
// Check that we do not leak a pointer.
|
// Check that we do not leak a pointer.
|
||||||
// Those pointers may lose part of their identity in codegen.
|
// 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);
|
let const_ = Const::Val(value, op.layout.ty);
|
||||||
Some(ConstOperand { span: rustc_span::DUMMY_SP, user_ty: None, const_ })
|
Some(ConstOperand { span: rustc_span::DUMMY_SP, user_ty: None, const_ })
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue