1
Fork 0

patterns: reject raw pointers that are not just integers

This commit is contained in:
Ralf Jung 2023-10-19 08:36:24 +02:00
parent 3089c315b1
commit bec88ad4aa
10 changed files with 92 additions and 32 deletions

View file

@ -97,11 +97,27 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
Ok(ty::ValTree::Leaf(val.assert_int()))
}
// Raw pointers are not allowed in type level constants, as we cannot properly test them for
// equality at compile-time (see `ptr_guaranteed_cmp`).
ty::RawPtr(_) => {
// Not all raw pointers are allowed, as we cannot properly test them for
// equality at compile-time (see `ptr_guaranteed_cmp`).
// However we allow those that are just integers in disguise.
// (We could allow wide raw pointers where both sides are integers in the future,
// but for now we reject them.)
let Ok(val) = ecx.read_scalar(place) else {
return Err(ValTreeCreationError::Other);
};
// We are in the CTFE machine, so ptr-to-int casts will fail.
// This can only be `Ok` if `val` already is an integer.
let Ok(val) = val.try_to_int() else {
return Err(ValTreeCreationError::Other);
};
// It's just a ScalarInt!
Ok(ty::ValTree::Leaf(val))
}
// Technically we could allow function pointers (represented as `ty::Instance`), but this is not guaranteed to
// agree with runtime equality tests.
ty::FnPtr(_) | ty::RawPtr(_) => Err(ValTreeCreationError::NonSupportedType),
ty::FnPtr(_) => Err(ValTreeCreationError::NonSupportedType),
ty::Ref(_, _, _) => {
let Ok(derefd_place)= ecx.deref_pointer(place) else {
@ -222,12 +238,14 @@ pub fn valtree_to_const_value<'tcx>(
assert!(valtree.unwrap_branch().is_empty());
mir::ConstValue::ZeroSized
}
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => match valtree {
ty::ValTree::Leaf(scalar_int) => mir::ConstValue::Scalar(Scalar::Int(scalar_int)),
ty::ValTree::Branch(_) => bug!(
"ValTrees for Bool, Int, Uint, Float or Char should have the form ValTree::Leaf"
),
},
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char | ty::RawPtr(_) => {
match valtree {
ty::ValTree::Leaf(scalar_int) => mir::ConstValue::Scalar(Scalar::Int(scalar_int)),
ty::ValTree::Branch(_) => bug!(
"ValTrees for Bool, Int, Uint, Float, Char or RawPtr should have the form ValTree::Leaf"
),
}
}
ty::Ref(_, inner_ty, _) => {
let mut ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No);
let imm = valtree_to_ref(&mut ecx, valtree, *inner_ty);
@ -281,7 +299,6 @@ pub fn valtree_to_const_value<'tcx>(
| ty::Coroutine(..)
| ty::CoroutineWitness(..)
| ty::FnPtr(_)
| ty::RawPtr(_)
| ty::Str
| ty::Slice(_)
| ty::Dynamic(..) => bug!("no ValTree should have been created for type {:?}", ty.kind()),