[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:
Wesley Wiser 2019-10-02 05:58:26 -04:00
parent f2023ac599
commit 3a8932d9b0
3 changed files with 28 additions and 29 deletions

View file

@ -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);
}
}
}

View 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;
}
}

View 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