diff options
| author | Keith Yeung <kungfukeith11@gmail.com> | 2017-11-16 15:32:13 -0800 |
|---|---|---|
| committer | Keith Yeung <kungfukeith11@gmail.com> | 2017-11-17 14:16:37 -0800 |
| commit | c9d1db7bc5fe027e60370dae7c0c15671fa2b7ff (patch) | |
| tree | f599306baf070097e227fb9e4de2e37bf95214ab /src/librustc_mir/dataflow/impls | |
| parent | 3be597acf3a0cac1939c4d9f0789510221667c96 (diff) | |
| download | rust-c9d1db7bc5fe027e60370dae7c0c15671fa2b7ff.tar.gz rust-c9d1db7bc5fe027e60370dae7c0c15671fa2b7ff.zip | |
Do not registor borrows for unsafe lvalues
Diffstat (limited to 'src/librustc_mir/dataflow/impls')
| -rw-r--r-- | src/librustc_mir/dataflow/impls/borrows.rs | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 928c07b7fbc..1e9d916def0 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -10,7 +10,7 @@ use rustc::mir::{self, Location, Mir}; use rustc::mir::visit::Visitor; -use rustc::ty::{Region, TyCtxt}; +use rustc::ty::{self, Region, TyCtxt}; use rustc::ty::RegionKind; use rustc::ty::RegionKind::ReScope; use rustc::util::nodemap::{FxHashMap, FxHashSet}; @@ -71,10 +71,14 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { mir: &'a Mir<'tcx>, nonlexical_regioncx: Option<&'a RegionInferenceContext<'tcx>>) -> Self { - let mut visitor = GatherBorrows { idx_vec: IndexVec::new(), - location_map: FxHashMap(), - region_map: FxHashMap(), - region_span_map: FxHashMap()}; + let mut visitor = GatherBorrows { + tcx, + mir, + idx_vec: IndexVec::new(), + location_map: FxHashMap(), + region_map: FxHashMap(), + region_span_map: FxHashMap() + }; visitor.visit_mir(mir); return Borrows { tcx: tcx, mir: mir, @@ -84,17 +88,22 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { region_span_map: visitor.region_span_map, nonlexical_regioncx }; - struct GatherBorrows<'tcx> { + struct GatherBorrows<'a, 'gcx: 'tcx, 'tcx: 'a> { + tcx: TyCtxt<'a, 'gcx, 'tcx>, + mir: &'a Mir<'tcx>, idx_vec: IndexVec<BorrowIndex, BorrowData<'tcx>>, location_map: FxHashMap<Location, BorrowIndex>, region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>, region_span_map: FxHashMap<RegionKind, Span>, } - impl<'tcx> Visitor<'tcx> for GatherBorrows<'tcx> { + + impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> { fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: mir::Location) { if let mir::Rvalue::Ref(region, kind, ref lvalue) = *rvalue { + if is_unsafe_lvalue(self.tcx, self.mir, lvalue) { return; } + let borrow = BorrowData { location: location, kind: kind, region: region, lvalue: lvalue.clone(), }; @@ -197,7 +206,8 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { } mir::StatementKind::Assign(_, ref rhs) => { - if let mir::Rvalue::Ref(region, _, _) = *rhs { + if let mir::Rvalue::Ref(region, _, ref lvalue) = *rhs { + if is_unsafe_lvalue(self.tcx, self.mir, lvalue) { return; } let index = self.location_map.get(&location).unwrap_or_else(|| { panic!("could not find BorrowIndex for location {:?}", location); }); @@ -248,3 +258,35 @@ impl<'a, 'gcx, 'tcx> DataflowOperator for Borrows<'a, 'gcx, 'tcx> { false // bottom = no Rvalue::Refs are active by default } } + +fn is_unsafe_lvalue<'a, 'gcx: 'tcx, 'tcx: 'a>( + tcx: TyCtxt<'a, 'gcx, 'tcx>, + mir: &'a Mir<'tcx>, + lvalue: &mir::Lvalue<'tcx> +) -> bool { + use self::mir::Lvalue::*; + use self::mir::ProjectionElem; + + match *lvalue { + Local(_) => false, + Static(ref static_) => tcx.is_static_mut(static_.def_id), + Projection(ref proj) => { + match proj.elem { + ProjectionElem::Field(..) | + ProjectionElem::Downcast(..) | + ProjectionElem::Subslice { .. } | + ProjectionElem::ConstantIndex { .. } | + ProjectionElem::Index(_) => { + is_unsafe_lvalue(tcx, mir, &proj.base) + } + ProjectionElem::Deref => { + let ty = proj.base.ty(mir, tcx).to_ty(tcx); + match ty.sty { + ty::TyRawPtr(..) => true, + _ => is_unsafe_lvalue(tcx, mir, &proj.base), + } + } + } + } + } +} |
