Skip to content

Commit a6403b0

Browse files
committed
Auto merge of #78147 - tmiasko:validate-storage, r=jonas-schievink
Assert that locals have storage when used The validator in visit_local asserts that local has a stroage when used, but visit_local is never called so validation is ineffective. Use super_statement and super_terminator to ensure that locals are visited.
2 parents 4f7612a + 3b7157d commit a6403b0

File tree

3 files changed

+24
-12
lines changed

3 files changed

+24
-12
lines changed

compiler/rustc_mir/src/transform/validate.rs

+21-12
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ use crate::dataflow::{Analysis, ResultsCursor};
55
use crate::util::storage::AlwaysLiveLocals;
66

77
use super::MirPass;
8-
use rustc_middle::mir::{
9-
interpret::Scalar,
10-
visit::{PlaceContext, Visitor},
11-
};
8+
use rustc_index::bit_set::BitSet;
9+
use rustc_middle::mir::interpret::Scalar;
10+
use rustc_middle::mir::traversal;
11+
use rustc_middle::mir::visit::{PlaceContext, Visitor};
1212
use rustc_middle::mir::{
1313
AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPhase, Operand, PlaceRef,
1414
Rvalue, SourceScope, Statement, StatementKind, Terminator, TerminatorKind, VarDebugInfo,
@@ -52,6 +52,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
5252
tcx,
5353
param_env,
5454
mir_phase,
55+
reachable_blocks: traversal::reachable_as_bitset(body),
5556
storage_liveness,
5657
place_cache: Vec::new(),
5758
}
@@ -157,6 +158,7 @@ struct TypeChecker<'a, 'tcx> {
157158
tcx: TyCtxt<'tcx>,
158159
param_env: ParamEnv<'tcx>,
159160
mir_phase: MirPhase,
161+
reachable_blocks: BitSet<BasicBlock>,
160162
storage_liveness: ResultsCursor<'a, 'tcx, MaybeStorageLive>,
161163
place_cache: Vec<PlaceRef<'tcx>>,
162164
}
@@ -232,7 +234,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
232234

233235
impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
234236
fn visit_local(&mut self, local: &Local, context: PlaceContext, location: Location) {
235-
if context.is_use() {
237+
if self.reachable_blocks.contains(location.block) && context.is_use() {
236238
// Uses of locals must occur while the local's storage is allocated.
237239
self.storage_liveness.seek_after_primary_effect(location);
238240
let locals_with_storage = self.storage_liveness.get();
@@ -249,13 +251,16 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
249251
}
250252

251253
fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
252-
// `Operand::Copy` is only supposed to be used with `Copy` types.
253-
if let Operand::Copy(place) = operand {
254-
let ty = place.ty(&self.body.local_decls, self.tcx).ty;
255-
let span = self.body.source_info(location).span;
256-
257-
if !ty.is_copy_modulo_regions(self.tcx.at(span), self.param_env) {
258-
self.fail(location, format!("`Operand::Copy` with non-`Copy` type {}", ty));
254+
// This check is somewhat expensive, so only run it when -Zvalidate-mir is passed.
255+
if self.tcx.sess.opts.debugging_opts.validate_mir {
256+
// `Operand::Copy` is only supposed to be used with `Copy` types.
257+
if let Operand::Copy(place) = operand {
258+
let ty = place.ty(&self.body.local_decls, self.tcx).ty;
259+
let span = self.body.source_info(location).span;
260+
261+
if !ty.is_copy_modulo_regions(self.tcx.at(span), self.param_env) {
262+
self.fail(location, format!("`Operand::Copy` with non-`Copy` type {}", ty));
263+
}
259264
}
260265
}
261266

@@ -341,6 +346,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
341346
}
342347
_ => {}
343348
}
349+
350+
self.super_statement(statement, location);
344351
}
345352

346353
fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
@@ -489,6 +496,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
489496
| TerminatorKind::Unreachable
490497
| TerminatorKind::GeneratorDrop => {}
491498
}
499+
500+
self.super_terminator(terminator, location);
492501
}
493502

494503
fn visit_source_scope(&mut self, scope: &SourceScope) {

src/test/codegen/avr/avr-func-addrspace.rs

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub trait Receiver { }
2323
pub struct Result<T, E> { _a: T, _b: E }
2424

2525
impl Copy for usize {}
26+
impl Copy for &usize {}
2627

2728
#[lang = "drop_in_place"]
2829
pub unsafe fn drop_in_place<T: ?Sized>(_: *mut T) {}

src/test/run-make-fulldeps/min-global-align/min_global_align.rs

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ trait Sized {}
1414

1515
#[lang = "copy"]
1616
trait Copy {}
17+
impl Copy for bool {}
18+
impl Copy for &bool {}
1719

1820
#[lang = "freeze"]
1921
trait Freeze {}

0 commit comments

Comments
 (0)