[const-prop] Correctly handle locals that can't be propagated
`const_prop()` now handles writing the Rvalue into the Place in the stack frame for us. So if we're not supported to propagate that value, we need to clear it.
This commit is contained in:
parent
f2023ac599
commit
3a8932d9b0
3 changed files with 28 additions and 29 deletions
|
@ -335,34 +335,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
}
|
||||
|
||||
fn get_const(&self, local: Local) -> Option<Const<'tcx>> {
|
||||
let l = &self.ecx.frame().locals[local];
|
||||
|
||||
// If the local is `Unitialized` or `Dead` then we haven't propagated a value into it.
|
||||
//
|
||||
// `InterpCx::access_local()` mostly takes care of this for us however, for ZSTs,
|
||||
// it will synthesize a value for us. In doing so, that will cause the
|
||||
// `get_const(l).is_empty()` assert right before we call `set_const()` in `visit_statement`
|
||||
// to fail.
|
||||
if let LocalValue::Uninitialized | LocalValue::Dead = l.value {
|
||||
return None;
|
||||
}
|
||||
|
||||
self.ecx.access_local(self.ecx.frame(), local, None).ok()
|
||||
}
|
||||
|
||||
fn set_const(&mut self, local: Local, c: Const<'tcx>) {
|
||||
let frame = self.ecx.frame_mut();
|
||||
|
||||
if let Some(layout) = frame.locals[local].layout.get() {
|
||||
debug_assert_eq!(c.layout, layout);
|
||||
}
|
||||
|
||||
frame.locals[local] = LocalState {
|
||||
value: LocalValue::Live(*c),
|
||||
layout: Cell::new(Some(c.layout)),
|
||||
};
|
||||
}
|
||||
|
||||
fn remove_const(&mut self, local: Local) {
|
||||
self.ecx.frame_mut().locals[local] = LocalState {
|
||||
value: LocalValue::Uninitialized,
|
||||
|
@ -735,10 +710,8 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
|
|||
place) {
|
||||
trace!("checking whether {:?} can be stored to {:?}", value, local);
|
||||
if self.can_const_prop[local] {
|
||||
trace!("storing {:?} to {:?}", value, local);
|
||||
assert!(self.get_const(local).is_none() ||
|
||||
self.get_const(local) == Some(value));
|
||||
self.set_const(local, value);
|
||||
trace!("stored {:?} to {:?}", value, local);
|
||||
assert_eq!(self.get_const(local), Some(value));
|
||||
|
||||
if self.should_const_prop() {
|
||||
self.replace_with_const(
|
||||
|
@ -747,6 +720,9 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
|
|||
statement.source_info,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
trace!("can't propagate {:?} to {:?}", value, local);
|
||||
self.remove_const(local);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
15
src/test/ui/consts/const-eval/issue-64970.rs
Normal file
15
src/test/ui/consts/const-eval/issue-64970.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
// run-pass
|
||||
|
||||
fn main() {
|
||||
foo(10);
|
||||
}
|
||||
|
||||
fn foo(mut n: i32) {
|
||||
if false {
|
||||
n = 0i32;
|
||||
}
|
||||
|
||||
if n > 0i32 {
|
||||
1i32 / n;
|
||||
}
|
||||
}
|
8
src/test/ui/consts/const-eval/issue-64970.stderr
Normal file
8
src/test/ui/consts/const-eval/issue-64970.stderr
Normal file
|
@ -0,0 +1,8 @@
|
|||
warning: unused arithmetic operation that must be used
|
||||
--> $DIR/issue-64970.rs:13:9
|
||||
|
|
||||
LL | 1i32 / n;
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(unused_must_use)]` on by default
|
||||
|
Loading…
Reference in a new issue