run unsafety checking before dead block collection

Fixes #45087.
This commit is contained in:
Ariel Ben-Yehuda 2017-11-05 18:09:39 +02:00
parent a6b1a81750
commit cd279a5b98
6 changed files with 33 additions and 6 deletions

View File

@ -473,6 +473,7 @@ define_dep_nodes!( <'tcx>
// Represents the MIR for a fn; also used as the task node for
// things read/modify that MIR.
[] MirConstQualif(DefId),
[] MirBuilt(DefId),
[] MirConst(DefId),
[] MirValidated(DefId),
[] MirOptimized(DefId),
@ -812,4 +813,3 @@ impl WorkProductId {
impl_stable_hash_for!(struct ::dep_graph::WorkProductId {
hash
});

View File

@ -151,6 +151,10 @@ define_maps! { <'tcx>
/// the value isn't known except to the pass itself.
[] fn mir_const_qualif: MirConstQualif(DefId) -> (u8, Rc<IdxSetBuf<mir::Local>>),
/// Fetch the MIR for a given def-id right after it's built - this includes
/// unreachable code.
[] fn mir_built: MirBuilt(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
/// Fetch the MIR for a given def-id up till the point where it is
/// ready for const evaluation.
///

View File

@ -712,6 +712,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
force!(crate_inherent_impls_overlap_check, LOCAL_CRATE)
},
DepKind::PrivacyAccessLevels => { force!(privacy_access_levels, LOCAL_CRATE); }
DepKind::MirBuilt => { force!(mir_built, def_id!()); }
DepKind::MirConstQualif => { force!(mir_const_qualif, def_id!()); }
DepKind::MirConst => { force!(mir_const, def_id!()); }
DepKind::MirValidated => { force!(mir_validated, def_id!()); }
@ -852,4 +853,3 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
true
}

View File

@ -344,8 +344,8 @@ fn unsafety_violations<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) ->
debug!("unsafety_violations({:?})", def_id);
// NB: this borrow is valid because all the consumers of
// `mir_const` force this.
let mir = &tcx.mir_const(def_id).borrow();
// `mir_built` force this.
let mir = &tcx.mir_built(def_id).borrow();
let visibility_scope_info = match mir.visibility_scope_info {
ClearOnDecode::Set(ref data) => data,

View File

@ -50,6 +50,7 @@ pub(crate) fn provide(providers: &mut Providers) {
self::check_unsafety::provide(providers);
*providers = Providers {
mir_keys,
mir_built,
mir_const,
mir_validated,
optimized_mir,
@ -103,9 +104,17 @@ fn mir_keys<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, krate: CrateNum)
Rc::new(set)
}
fn mir_built<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Steal<Mir<'tcx>> {
let mir = build::mir_build(tcx, def_id);
tcx.alloc_steal_mir(mir)
}
fn mir_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Steal<Mir<'tcx>> {
let mut mir = build::mir_build(tcx, def_id);
// Unsafety check uses the raw mir, so make sure it is run
let _ = tcx.unsafety_violations(def_id);
let source = MirSource::from_local_def_id(tcx, def_id);
let mut mir = tcx.mir_built(def_id).steal();
transform::run_suite(tcx, source, MIR_CONST, &mut mir);
tcx.alloc_steal_mir(mir)
}
@ -117,7 +126,6 @@ fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
// this point, before we steal the mir-const result.
let _ = tcx.mir_const_qualif(def_id);
}
let _ = tcx.unsafety_violations(def_id);
let mut mir = tcx.mir_const(def_id).steal();
transform::run_suite(tcx, source, MIR_VALIDATED, &mut mir);

View File

@ -0,0 +1,15 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn main() {
return;
*(1 as *mut u32) = 42;
//~^ ERROR dereference of raw pointer requires unsafe
}