Skip to content

Commit

Permalink
[const-prop] Correctly handle locals that can't be propagated
Browse files Browse the repository at this point in the history
`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.
  • Loading branch information
wesleywiser committed Oct 2, 2019
1 parent f2023ac commit 3a8932d
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 29 deletions.
34 changes: 5 additions & 29 deletions src/librustc_mir/transform/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(
Expand All @@ -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);
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions src/test/ui/consts/const-eval/issue-64970.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 8 additions & 0 deletions src/test/ui/consts/const-eval/issue-64970.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 3a8932d

Please sign in to comment.