diff --git a/.mailmap b/.mailmap index 679aa55d31458..1bb0aed4a6a62 100644 --- a/.mailmap +++ b/.mailmap @@ -139,6 +139,7 @@ Kang Seonghoon Keegan McAllister Kevin Butler Kyeongwoon Lee +Laurențiu Nicola Lee Jeffery Lee Jeffery Lee Wondong Lennart Kudling diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index ad35204804755..5c5ebff6594d9 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -115,6 +115,8 @@ #![feature(wasm_target_feature)] #![feature(avx512_target_feature)] #![feature(cmpxchg16b_target_feature)] +#![feature(f16c_target_feature)] +#![feature(rtm_target_feature)] #![feature(const_slice_len)] #![feature(const_str_as_bytes)] #![feature(const_str_len)] diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index dd33fae0d6197..2f19f591830f9 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -151,17 +151,17 @@ macro_rules! make_mir_visitor { self.super_place(place, context, location); } - fn visit_projection(&mut self, - place: & $($mutability)? Projection<'tcx>, + fn visit_place_base(&mut self, + place_base: & $($mutability)? PlaceBase<'tcx>, context: PlaceContext, location: Location) { - self.super_projection(place, context, location); + self.super_place_base(place_base, context, location); } - fn visit_projection_elem(&mut self, - place: & $($mutability)? PlaceElem<'tcx>, - location: Location) { - self.super_projection_elem(place, location); + fn visit_projection(&mut self, + place: & $($mutability)? Projection<'tcx>, + location: Location) { + self.super_projection(place, location); } fn visit_constant(&mut self, @@ -676,36 +676,40 @@ macro_rules! make_mir_visitor { context: PlaceContext, location: Location) { match place { - Place::Base(PlaceBase::Local(local)) => { - self.visit_local(local, context, location); - } - Place::Base(PlaceBase::Static(box Static { kind: _, ty })) => { - self.visit_ty(& $($mutability)? *ty, TyContext::Location(location)); + Place::Base(place_base) => { + self.visit_place_base(place_base, context, location); } Place::Projection(proj) => { - self.visit_projection(proj, context, location); + let context = if context.is_mutating_use() { + PlaceContext::MutatingUse(MutatingUseContext::Projection) + } else { + PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) + }; + + self.visit_place(& $($mutability)? proj.base, context, location); + self.visit_projection(proj, location); } } } - fn super_projection(&mut self, - proj: & $($mutability)? Projection<'tcx>, + fn super_place_base(&mut self, + place_base: & $($mutability)? PlaceBase<'tcx>, context: PlaceContext, location: Location) { - let Projection { base, elem } = proj; - let context = if context.is_mutating_use() { - PlaceContext::MutatingUse(MutatingUseContext::Projection) - } else { - PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) - }; - self.visit_place(base, context, location); - self.visit_projection_elem(elem, location); + match place_base { + PlaceBase::Local(local) => { + self.visit_local(local, context, location); + } + PlaceBase::Static(box Static { kind: _, ty }) => { + self.visit_ty(& $($mutability)? *ty, TyContext::Location(location)); + } + } } - fn super_projection_elem(&mut self, - proj: & $($mutability)? PlaceElem<'tcx>, - location: Location) { - match proj { + fn super_projection(&mut self, + proj: & $($mutability)? Projection<'tcx>, + location: Location) { + match & $($mutability)? proj.elem { ProjectionElem::Deref => { } ProjectionElem::Subslice { from: _, to: _ } => { diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index bb6a13ed15a52..549608bf7ee5f 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -154,51 +154,62 @@ impl<'mir, 'a: 'mir, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> context: PlaceContext, location: Location) { debug!("visit_place(place={:?}, context={:?})", place, context); + let mut context = context; let cx = self.fx.cx; - if let mir::Place::Projection(ref proj) = *place { - // Allow uses of projections that are ZSTs or from scalar fields. - let is_consume = match context { - PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) | - PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true, - _ => false - }; - if is_consume { - let base_ty = proj.base.ty(self.fx.mir, cx.tcx()); - let base_ty = self.fx.monomorphize(&base_ty); - - // ZSTs don't require any actual memory access. - let elem_ty = base_ty - .projection_ty(cx.tcx(), &proj.elem) - .ty; - let elem_ty = self.fx.monomorphize(&elem_ty); - if cx.layout_of(elem_ty).is_zst() { - return; - } - - if let mir::ProjectionElem::Field(..) = proj.elem { - let layout = cx.layout_of(base_ty.ty); - if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) { - // Recurse with the same context, instead of `Projection`, - // potentially stopping at non-operand projections, - // which would trigger `not_ssa` on locals. - self.visit_place(&proj.base, context, location); + place.iterate(|place_base, place_projections| { + for proj in place_projections { + // Allow uses of projections that are ZSTs or from scalar fields. + let is_consume = match context { + PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) | + PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true, + _ => false + }; + if is_consume { + let base_ty = proj.base.ty(self.fx.mir, cx.tcx()); + let base_ty = self.fx.monomorphize(&base_ty); + + // ZSTs don't require any actual memory access. + let elem_ty = base_ty + .projection_ty(cx.tcx(), &proj.elem) + .ty; + let elem_ty = self.fx.monomorphize(&elem_ty); + if cx.layout_of(elem_ty).is_zst() { return; } + + if let mir::ProjectionElem::Field(..) = proj.elem { + let layout = cx.layout_of(base_ty.ty); + if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) { + // Recurse with the same context, instead of `Projection`, + // potentially stopping at non-operand projections, + // which would trigger `not_ssa` on locals. + continue; + } + } } - } - // A deref projection only reads the pointer, never needs the place. - if let mir::ProjectionElem::Deref = proj.elem { - return self.visit_place( - &proj.base, - PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy), - location - ); + // A deref projection only reads the pointer, never needs the place. + if let mir::ProjectionElem::Deref = proj.elem { + return self.visit_place( + &proj.base, + PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy), + location + ); + } + + context = if context.is_mutating_use() { + PlaceContext::MutatingUse(MutatingUseContext::Projection) + } else { + PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) + }; } - } - self.super_place(place, context, location); + // Default base visit behavior + if let mir::PlaceBase::Local(local) = place_base { + self.visit_local(local, context, location); + } + }); } fn visit_local(&mut self, diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index eed051449e155..91b4af9655a43 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -185,7 +185,7 @@ use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind, Instance}; use rustc::ty::print::obsolete::DefPathBasedNames; use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc::session::config::EntryFnType; -use rustc::mir::{self, Location, Place, PlaceBase, Promoted, Static, StaticKind}; +use rustc::mir::{self, Location, PlaceBase, Promoted, Static, StaticKind}; use rustc::mir::visit::Visitor as MirVisitor; use rustc::mir::mono::{MonoItem, InstantiationMode}; use rustc::mir::interpret::{Scalar, GlobalId, GlobalAlloc, ErrorHandled}; @@ -655,14 +655,12 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { self.super_terminator_kind(kind, location); } - fn visit_place(&mut self, - place: &mir::Place<'tcx>, - context: mir::visit::PlaceContext, - location: Location) { - match place { - Place::Base( - PlaceBase::Static(box Static{ kind:StaticKind::Static(def_id), .. }) - ) => { + fn visit_place_base(&mut self, + place_base: &mir::PlaceBase<'tcx>, + _context: mir::visit::PlaceContext, + location: Location) { + match place_base { + PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. }) => { debug!("visiting static {:?} @ {:?}", def_id, location); let tcx = self.tcx; @@ -671,10 +669,13 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { self.output.push(MonoItem::Static(*def_id)); } } - _ => {} + PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. }) => { + // FIXME: should we handle promoteds here instead of eagerly in collect_neighbours? + } + PlaceBase::Local(_) => { + // Locals have no relevance for collector + } } - - self.super_place(place, context, location); } } diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 8ec8a8fa12eec..4e8cc124e5040 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -199,11 +199,39 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, - location: Location) { - match place { - &Place::Projection(box Projection { - ref base, ref elem - }) => { + _location: Location) { + place.iterate(|place_base, place_projections| { + match place_base { + PlaceBase::Local(..) => { + // Locals are safe. + } + PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. }) => { + bug!("unsafety checking should happen before promotion") + } + PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. }) => { + if self.tcx.is_mutable_static(*def_id) { + self.require_unsafe("use of mutable static", + "mutable statics can be mutated by multiple threads: aliasing \ + violations or data races will cause undefined behavior", + UnsafetyViolationKind::General); + } else if self.tcx.is_foreign_item(*def_id) { + let source_info = self.source_info; + let lint_root = + self.source_scope_local_data[source_info.scope].lint_root; + self.register_violations(&[UnsafetyViolation { + source_info, + description: InternedString::intern("use of extern static"), + details: InternedString::intern( + "extern statics are not controlled by the Rust type system: \ + invalid data, aliasing violations or data races will cause \ + undefined behavior"), + kind: UnsafetyViolationKind::ExternStatic(lint_root) + }], &[]); + } + } + } + + for proj in place_projections { if context.is_borrow() { if util::is_disaligned(self.tcx, self.mir, self.param_env, place) { let source_info = self.source_info; @@ -220,7 +248,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { }], &[]); } } - let is_borrow_of_interior_mut = context.is_borrow() && !base + let is_borrow_of_interior_mut = context.is_borrow() && !proj.base .ty(self.mir, self.tcx) .ty .is_freeze(self.tcx, self.param_env, self.source_info.span); @@ -236,7 +264,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { ); } let old_source_info = self.source_info; - if let &Place::Base(PlaceBase::Local(local)) = base { + if let Place::Base(PlaceBase::Local(local)) = proj.base { if self.mir.local_decls[local].internal { // Internal locals are used in the `move_val_init` desugaring. // We want to check unsafety against the source info of the @@ -244,7 +272,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { self.source_info = self.mir.local_decls[local].source_info; } } - let base_ty = base.ty(self.mir, self.tcx).ty; + let base_ty = proj.base.ty(self.mir, self.tcx).ty; match base_ty.sty { ty::RawPtr(..) => { self.require_unsafe("dereference of raw pointer", @@ -260,8 +288,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { MutatingUseContext::AsmOutput ) { - let elem_ty = match elem { - &ProjectionElem::Field(_, ty) => ty, + let elem_ty = match proj.elem { + ProjectionElem::Field(_, ty) => ty, _ => span_bug!( self.source_info.span, "non-field projection {:?} from union?", @@ -292,36 +320,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { } self.source_info = old_source_info; } - &Place::Base(PlaceBase::Local(..)) => { - // locals are safe - } - &Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) => { - bug!("unsafety checking should happen before promotion") - } - &Place::Base( - PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. }) - ) => { - if self.tcx.is_mutable_static(def_id) { - self.require_unsafe("use of mutable static", - "mutable statics can be mutated by multiple threads: aliasing violations \ - or data races will cause undefined behavior", - UnsafetyViolationKind::General); - } else if self.tcx.is_foreign_item(def_id) { - let source_info = self.source_info; - let lint_root = - self.source_scope_local_data[source_info.scope].lint_root; - self.register_violations(&[UnsafetyViolation { - source_info, - description: InternedString::intern("use of extern static"), - details: InternedString::intern( - "extern statics are not controlled by the Rust type system: invalid \ - data, aliasing violations or data races will cause undefined behavior"), - kind: UnsafetyViolationKind::ExternStatic(lint_root) - }], &[]); - } - } - }; - self.super_place(place, context, location); + }); } } diff --git a/src/stdsimd b/src/stdsimd index 4bf456c35e85f..87d19d212ef17 160000 --- a/src/stdsimd +++ b/src/stdsimd @@ -1 +1 @@ -Subproject commit 4bf456c35e85fcca5cf95008401af8ab25abf850 +Subproject commit 87d19d212ef172a6cfbb3a330ac1c33da16cced6