Skip to content

Commit

Permalink
Auto merge of #78147 - tmiasko:validate-storage, r=jonas-schievink
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Nov 1, 2020
2 parents 4f7612a + 3b7157d commit a6403b0
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 12 deletions.
33 changes: 21 additions & 12 deletions compiler/rustc_mir/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use crate::dataflow::{Analysis, ResultsCursor};
use crate::util::storage::AlwaysLiveLocals;

use super::MirPass;
use rustc_middle::mir::{
interpret::Scalar,
visit::{PlaceContext, Visitor},
};
use rustc_index::bit_set::BitSet;
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::traversal;
use rustc_middle::mir::visit::{PlaceContext, Visitor};
use rustc_middle::mir::{
AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPhase, Operand, PlaceRef,
Rvalue, SourceScope, Statement, StatementKind, Terminator, TerminatorKind, VarDebugInfo,
Expand Down Expand Up @@ -52,6 +52,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
tcx,
param_env,
mir_phase,
reachable_blocks: traversal::reachable_as_bitset(body),
storage_liveness,
place_cache: Vec::new(),
}
Expand Down Expand Up @@ -157,6 +158,7 @@ struct TypeChecker<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
mir_phase: MirPhase,
reachable_blocks: BitSet<BasicBlock>,
storage_liveness: ResultsCursor<'a, 'tcx, MaybeStorageLive>,
place_cache: Vec<PlaceRef<'tcx>>,
}
Expand Down Expand Up @@ -232,7 +234,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {

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

fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
// `Operand::Copy` is only supposed to be used with `Copy` types.
if let Operand::Copy(place) = operand {
let ty = place.ty(&self.body.local_decls, self.tcx).ty;
let span = self.body.source_info(location).span;

if !ty.is_copy_modulo_regions(self.tcx.at(span), self.param_env) {
self.fail(location, format!("`Operand::Copy` with non-`Copy` type {}", ty));
// This check is somewhat expensive, so only run it when -Zvalidate-mir is passed.
if self.tcx.sess.opts.debugging_opts.validate_mir {
// `Operand::Copy` is only supposed to be used with `Copy` types.
if let Operand::Copy(place) = operand {
let ty = place.ty(&self.body.local_decls, self.tcx).ty;
let span = self.body.source_info(location).span;

if !ty.is_copy_modulo_regions(self.tcx.at(span), self.param_env) {
self.fail(location, format!("`Operand::Copy` with non-`Copy` type {}", ty));
}
}
}

Expand Down Expand Up @@ -341,6 +346,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
_ => {}
}

self.super_statement(statement, location);
}

fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
Expand Down Expand Up @@ -489,6 +496,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
| TerminatorKind::Unreachable
| TerminatorKind::GeneratorDrop => {}
}

self.super_terminator(terminator, location);
}

fn visit_source_scope(&mut self, scope: &SourceScope) {
Expand Down
1 change: 1 addition & 0 deletions src/test/codegen/avr/avr-func-addrspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub trait Receiver { }
pub struct Result<T, E> { _a: T, _b: E }

impl Copy for usize {}
impl Copy for &usize {}

#[lang = "drop_in_place"]
pub unsafe fn drop_in_place<T: ?Sized>(_: *mut T) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ trait Sized {}

#[lang = "copy"]
trait Copy {}
impl Copy for bool {}
impl Copy for &bool {}

#[lang = "freeze"]
trait Freeze {}
Expand Down

0 comments on commit a6403b0

Please sign in to comment.