Skip to content

Commit 1d36e3a

Browse files
committed
Lint missing StorageDead when returning from functions
1 parent 7a246dd commit 1d36e3a

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

Diff for: compiler/rustc_mir_transform/src/lint.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,24 @@ pub fn lint_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, when: String) {
1818
.iterate_to_fixpoint()
1919
.into_results_cursor(body);
2020

21-
Lint { tcx, when, body, reachable_blocks, storage_liveness }.visit_body(body);
21+
Lint {
22+
tcx,
23+
when,
24+
body,
25+
is_fn_like: tcx.def_kind(body.source.def_id()).is_fn_like(),
26+
always_live_locals,
27+
reachable_blocks,
28+
storage_liveness,
29+
}
30+
.visit_body(body);
2231
}
2332

2433
struct Lint<'a, 'tcx> {
2534
tcx: TyCtxt<'tcx>,
2635
when: String,
2736
body: &'a Body<'tcx>,
37+
is_fn_like: bool,
38+
always_live_locals: &'a BitSet<Local>,
2839
reachable_blocks: BitSet<BasicBlock>,
2940
storage_liveness: ResultsCursor<'a, 'tcx, MaybeStorageLive<'a>>,
3041
}
@@ -74,4 +85,27 @@ impl<'a, 'tcx> Visitor<'tcx> for Lint<'a, 'tcx> {
7485

7586
self.super_statement(statement, location);
7687
}
88+
89+
fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
90+
match terminator.kind {
91+
TerminatorKind::Return => {
92+
if self.is_fn_like && self.reachable_blocks.contains(location.block) {
93+
self.storage_liveness.seek_after_primary_effect(location);
94+
for local in self.storage_liveness.get().iter() {
95+
if !self.always_live_locals.contains(local) {
96+
self.fail(
97+
location,
98+
format!(
99+
"local {local:?} still has storage when returning from function"
100+
),
101+
);
102+
}
103+
}
104+
}
105+
}
106+
_ => {}
107+
}
108+
109+
self.super_terminator(terminator, location);
110+
}
77111
}

Diff for: tests/ui/mir/lint/storage-return.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// compile-flags: -Zlint-mir -Ztreat-err-as-bug
2+
// failure-status: 101
3+
// dont-check-compiler-stderr
4+
// error-pattern: has storage when returning
5+
#![feature(custom_mir, core_intrinsics)]
6+
extern crate core;
7+
use core::intrinsics::mir::*;
8+
9+
#[custom_mir(dialect = "built")]
10+
fn main() {
11+
mir!(
12+
let a: ();
13+
{
14+
StorageLive(a);
15+
RET = a;
16+
Return()
17+
}
18+
)
19+
}

0 commit comments

Comments
 (0)