interpret: fail more gracefully on uninit unsized locals
This commit is contained in:
parent
8b8110e146
commit
25e9b79060
@ -337,7 +337,7 @@ fn valtree_into_mplace<'tcx>(
|
|||||||
|
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::FnDef(_, _) => {
|
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 => {
|
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => {
|
||||||
let scalar_int = valtree.unwrap_leaf();
|
let scalar_int = valtree.unwrap_leaf();
|
||||||
|
@ -245,6 +245,12 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
|
|||||||
impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
|
impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
|
||||||
pub fn len(&self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> {
|
pub fn len(&self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> {
|
||||||
if self.layout.is_unsized() {
|
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.
|
// There are no unsized immediates.
|
||||||
self.assert_mem_place().len(cx)
|
self.assert_mem_place().len(cx)
|
||||||
} else {
|
} else {
|
||||||
|
@ -134,6 +134,9 @@ pub enum InvalidProgramInfo<'tcx> {
|
|||||||
FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError),
|
FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError),
|
||||||
/// SizeOf of unsized type was requested.
|
/// SizeOf of unsized type was requested.
|
||||||
SizeOfUnsizedType(Ty<'tcx>),
|
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<'_> {
|
impl fmt::Display for InvalidProgramInfo<'_> {
|
||||||
@ -150,6 +153,7 @@ impl fmt::Display for InvalidProgramInfo<'_> {
|
|||||||
Layout(ref err) => write!(f, "{err}"),
|
Layout(ref err) => write!(f, "{err}"),
|
||||||
FnAbiAdjustForForeignAbi(ref err) => write!(f, "{err}"),
|
FnAbiAdjustForForeignAbi(ref err) => write!(f, "{err}"),
|
||||||
SizeOfUnsizedType(ty) => write!(f, "size_of called on unsized type `{ty}`"),
|
SizeOfUnsizedType(ty) => write!(f, "size_of called on unsized type `{ty}`"),
|
||||||
|
UninitUnsizedLocal => write!(f, "unsized local is used while uninitialized"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
9
tests/ui/const_prop/unsized-local-ice.rs
Normal file
9
tests/ui/const_prop/unsized-local-ice.rs
Normal 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() {}
|
Loading…
x
Reference in New Issue
Block a user