mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 07:44:10 +00:00
Visit only reachable blocks in MIR lint
No functional changes - all checks have been emitted conditionally on block being rechable already.
This commit is contained in:
parent
4c5ce1f0d5
commit
12b92c8a87
@ -11,7 +11,6 @@ use rustc_mir_dataflow::{Analysis, ResultsCursor};
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
pub fn lint_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, when: String) {
|
pub fn lint_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, when: String) {
|
||||||
let reachable_blocks = traversal::reachable_as_bitset(body);
|
|
||||||
let always_live_locals = &always_storage_live_locals(body);
|
let always_live_locals = &always_storage_live_locals(body);
|
||||||
|
|
||||||
let maybe_storage_live = MaybeStorageLive::new(Cow::Borrowed(always_live_locals))
|
let maybe_storage_live = MaybeStorageLive::new(Cow::Borrowed(always_live_locals))
|
||||||
@ -24,17 +23,18 @@ pub fn lint_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, when: String) {
|
|||||||
.iterate_to_fixpoint()
|
.iterate_to_fixpoint()
|
||||||
.into_results_cursor(body);
|
.into_results_cursor(body);
|
||||||
|
|
||||||
Lint {
|
let mut lint = Lint {
|
||||||
tcx,
|
tcx,
|
||||||
when,
|
when,
|
||||||
body,
|
body,
|
||||||
is_fn_like: tcx.def_kind(body.source.def_id()).is_fn_like(),
|
is_fn_like: tcx.def_kind(body.source.def_id()).is_fn_like(),
|
||||||
always_live_locals,
|
always_live_locals,
|
||||||
reachable_blocks,
|
|
||||||
maybe_storage_live,
|
maybe_storage_live,
|
||||||
maybe_storage_dead,
|
maybe_storage_dead,
|
||||||
|
};
|
||||||
|
for (bb, data) in traversal::reachable(body) {
|
||||||
|
lint.visit_basic_block_data(bb, data);
|
||||||
}
|
}
|
||||||
.visit_body(body);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Lint<'a, 'tcx> {
|
struct Lint<'a, 'tcx> {
|
||||||
@ -43,7 +43,6 @@ struct Lint<'a, 'tcx> {
|
|||||||
body: &'a Body<'tcx>,
|
body: &'a Body<'tcx>,
|
||||||
is_fn_like: bool,
|
is_fn_like: bool,
|
||||||
always_live_locals: &'a BitSet<Local>,
|
always_live_locals: &'a BitSet<Local>,
|
||||||
reachable_blocks: BitSet<BasicBlock>,
|
|
||||||
maybe_storage_live: ResultsCursor<'a, 'tcx, MaybeStorageLive<'a>>,
|
maybe_storage_live: ResultsCursor<'a, 'tcx, MaybeStorageLive<'a>>,
|
||||||
maybe_storage_dead: ResultsCursor<'a, 'tcx, MaybeStorageDead<'a>>,
|
maybe_storage_dead: ResultsCursor<'a, 'tcx, MaybeStorageDead<'a>>,
|
||||||
}
|
}
|
||||||
@ -67,7 +66,7 @@ impl<'a, 'tcx> Lint<'a, 'tcx> {
|
|||||||
|
|
||||||
impl<'a, 'tcx> Visitor<'tcx> for Lint<'a, 'tcx> {
|
impl<'a, 'tcx> Visitor<'tcx> for Lint<'a, 'tcx> {
|
||||||
fn visit_local(&mut self, local: Local, context: PlaceContext, location: Location) {
|
fn visit_local(&mut self, local: Local, context: PlaceContext, location: Location) {
|
||||||
if self.reachable_blocks.contains(location.block) && context.is_use() {
|
if context.is_use() {
|
||||||
self.maybe_storage_dead.seek_after_primary_effect(location);
|
self.maybe_storage_dead.seek_after_primary_effect(location);
|
||||||
if self.maybe_storage_dead.get().contains(local) {
|
if self.maybe_storage_dead.get().contains(local) {
|
||||||
self.fail(location, format!("use of local {local:?}, which has no storage here"));
|
self.fail(location, format!("use of local {local:?}, which has no storage here"));
|
||||||
@ -78,14 +77,12 @@ impl<'a, 'tcx> Visitor<'tcx> for Lint<'a, 'tcx> {
|
|||||||
fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
|
fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
|
||||||
match statement.kind {
|
match statement.kind {
|
||||||
StatementKind::StorageLive(local) => {
|
StatementKind::StorageLive(local) => {
|
||||||
if self.reachable_blocks.contains(location.block) {
|
self.maybe_storage_live.seek_before_primary_effect(location);
|
||||||
self.maybe_storage_live.seek_before_primary_effect(location);
|
if self.maybe_storage_live.get().contains(local) {
|
||||||
if self.maybe_storage_live.get().contains(local) {
|
self.fail(
|
||||||
self.fail(
|
location,
|
||||||
location,
|
format!("StorageLive({local:?}) which already has storage here"),
|
||||||
format!("StorageLive({local:?}) which already has storage here"),
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -97,7 +94,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Lint<'a, 'tcx> {
|
|||||||
fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
|
fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
|
||||||
match terminator.kind {
|
match terminator.kind {
|
||||||
TerminatorKind::Return => {
|
TerminatorKind::Return => {
|
||||||
if self.is_fn_like && self.reachable_blocks.contains(location.block) {
|
if self.is_fn_like {
|
||||||
self.maybe_storage_live.seek_after_primary_effect(location);
|
self.maybe_storage_live.seek_after_primary_effect(location);
|
||||||
for local in self.maybe_storage_live.get().iter() {
|
for local in self.maybe_storage_live.get().iter() {
|
||||||
if !self.always_live_locals.contains(local) {
|
if !self.always_live_locals.contains(local) {
|
||||||
|
Loading…
Reference in New Issue
Block a user