Rollup merge of #110943 - RalfJung:interpret-unsized-arg-ice, r=oli-obk

interpret: fail more gracefully on uninit unsized locals

r? `@oli-obk`

Fixes https://github.com/rust-lang/rust/issues/68538
This commit is contained in:
Dylan DPC 2023-05-04 00:17:25 +05:30 committed by GitHub
commit 8b7080b15b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 20 additions and 1 deletions

View File

@ -337,7 +337,7 @@ fn valtree_into_mplace<'tcx>(
match ty.kind() {
ty::FnDef(_, _) => {
ecx.write_immediate(Immediate::Uninit, &place.into()).unwrap();
// Zero-sized type, nothing to do.
}
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => {
let scalar_int = valtree.unwrap_leaf();

View File

@ -245,6 +245,12 @@ pub fn to_const_int(self) -> ConstInt {
impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
pub fn len(&self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> {
if self.layout.is_unsized() {
if matches!(self.op, Operand::Immediate(Immediate::Uninit)) {
// Uninit unsized places shouldn't occur. In the interpreter we have them
// temporarily for unsized arguments before their value is put in; in ConstProp they
// remain uninit and this code can actually be reached.
throw_inval!(UninitUnsizedLocal);
}
// There are no unsized immediates.
self.assert_mem_place().len(cx)
} else {

View File

@ -134,6 +134,9 @@ pub enum InvalidProgramInfo<'tcx> {
FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError),
/// SizeOf of unsized type was requested.
SizeOfUnsizedType(Ty<'tcx>),
/// An unsized local was accessed without having been initialized.
/// This is not meaningful as we can't even have backing memory for such locals.
UninitUnsizedLocal,
}
impl fmt::Display for InvalidProgramInfo<'_> {
@ -150,6 +153,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Layout(ref err) => write!(f, "{err}"),
FnAbiAdjustForForeignAbi(ref err) => write!(f, "{err}"),
SizeOfUnsizedType(ty) => write!(f, "size_of called on unsized type `{ty}`"),
UninitUnsizedLocal => write!(f, "unsized local is used while uninitialized"),
}
}
}

View File

@ -0,0 +1,9 @@
// build-pass
//! Regression test for <https://github.com/rust-lang/rust/issues/68538>.
#![feature(unsized_fn_params)]
pub fn take_unsized_slice(s: [u8]) {
s[0];
}
fn main() {}