Rollup merge of #107524 - cjgillot:both-storage, r=RalfJung
Remove both StorageLive and StorageDead in CopyProp. Fixes https://github.com/rust-lang/rust/issues/107511 https://github.com/rust-lang/rust/pull/106908 removed StorageDead without the accompanying StorageLive. In loops, execution would see repeated StorageLive, without any StorageDead, which is UB. So when removing storage statements, we have to remove both StorageLive and StorageDead. ~I also added a MIR validation pass for StorageLive. It may be a bit overzealous.~
This commit is contained in:
commit
6917040cf0
20 changed files with 176 additions and 48 deletions
|
@ -162,17 +162,20 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, loc: Location) {
|
||||
if let StatementKind::StorageDead(l) = stmt.kind
|
||||
&& self.storage_to_remove.contains(l)
|
||||
{
|
||||
stmt.make_nop();
|
||||
} else if let StatementKind::Assign(box (ref place, ref mut rvalue)) = stmt.kind
|
||||
&& place.as_local().is_some()
|
||||
{
|
||||
// Do not replace assignments.
|
||||
self.visit_rvalue(rvalue, loc)
|
||||
} else {
|
||||
self.super_statement(stmt, loc);
|
||||
match stmt.kind {
|
||||
// When removing storage statements, we need to remove both (#107511).
|
||||
StatementKind::StorageLive(l) | StatementKind::StorageDead(l)
|
||||
if self.storage_to_remove.contains(l) =>
|
||||
{
|
||||
stmt.make_nop()
|
||||
}
|
||||
StatementKind::Assign(box (ref place, ref mut rvalue))
|
||||
if place.as_local().is_some() =>
|
||||
{
|
||||
// Do not replace assignments.
|
||||
self.visit_rvalue(rvalue, loc)
|
||||
}
|
||||
_ => self.super_statement(stmt, loc),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue