Skip to content

Commit

Permalink
run unsafety checking before dead block collection
Browse files Browse the repository at this point in the history
Fixes #45087.
  • Loading branch information
arielb1 committed Nov 6, 2017
1 parent a6b1a81 commit cd279a5
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -812,4 +813,3 @@ impl WorkProductId {
impl_stable_hash_for!(struct ::dep_graph::WorkProductId {
hash
});

4 changes: 4 additions & 0 deletions src/librustc/ty/maps/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/maps/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!()); }
Expand Down Expand Up @@ -852,4 +853,3 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,

true
}

4 changes: 2 additions & 2 deletions src/librustc_mir/transform/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
12 changes: 10 additions & 2 deletions src/librustc_mir/transform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
}
Expand All @@ -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);
Expand Down
15 changes: 15 additions & 0 deletions src/test/compile-fail/issue-45087-unreachable-unsafe.rs
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit cd279a5

Please sign in to comment.