From 85b155f6f1941be159b5a2790b5396fece101f64 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 9 May 2016 14:26:15 -0400 Subject: trans: Don't try to place declarations during codegen unit partitioning. --- src/test/codegen-units/partitioning/local-drop-glue.rs | 2 +- src/test/codegen-units/partitioning/local-generic.rs | 8 ++++---- .../codegen-units/partitioning/methods-are-with-self-type.rs | 12 ++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src/test') diff --git a/src/test/codegen-units/partitioning/local-drop-glue.rs b/src/test/codegen-units/partitioning/local-drop-glue.rs index 1edc3d5d2e2..04ebef645ec 100644 --- a/src/test/codegen-units/partitioning/local-drop-glue.rs +++ b/src/test/codegen-units/partitioning/local-drop-glue.rs @@ -23,7 +23,7 @@ struct Struct { } impl Drop for Struct { - //~ TRANS_ITEM fn local_drop_glue::{{impl}}[0]::drop[0] @@ local_drop_glue[WeakODR] local_drop_glue-mod1[Declaration] + //~ TRANS_ITEM fn local_drop_glue::{{impl}}[0]::drop[0] @@ local_drop_glue[WeakODR] fn drop(&mut self) {} } diff --git a/src/test/codegen-units/partitioning/local-generic.rs b/src/test/codegen-units/partitioning/local-generic.rs index 4c762ebdc2e..e38e676b95c 100644 --- a/src/test/codegen-units/partitioning/local-generic.rs +++ b/src/test/codegen-units/partitioning/local-generic.rs @@ -19,10 +19,10 @@ // Used in different modules/codegen units but always instantiated in the same // codegen unit. -//~ TRANS_ITEM fn local_generic::generic[0] @@ local_generic.volatile[WeakODR] local_generic[Declaration] -//~ TRANS_ITEM fn local_generic::generic[0] @@ local_generic.volatile[WeakODR] local_generic-mod1[Declaration] -//~ TRANS_ITEM fn local_generic::generic[0] @@ local_generic.volatile[WeakODR] local_generic-mod1-mod1[Declaration] -//~ TRANS_ITEM fn local_generic::generic[0]<&str> @@ local_generic.volatile[WeakODR] local_generic-mod2[Declaration] +//~ TRANS_ITEM fn local_generic::generic[0] @@ local_generic.volatile[WeakODR] +//~ TRANS_ITEM fn local_generic::generic[0] @@ local_generic.volatile[WeakODR] +//~ TRANS_ITEM fn local_generic::generic[0] @@ local_generic.volatile[WeakODR] +//~ TRANS_ITEM fn local_generic::generic[0]<&str> @@ local_generic.volatile[WeakODR] pub fn generic(x: T) -> T { x } //~ TRANS_ITEM fn local_generic::user[0] @@ local_generic[WeakODR] diff --git a/src/test/codegen-units/partitioning/methods-are-with-self-type.rs b/src/test/codegen-units/partitioning/methods-are-with-self-type.rs index 390bade153c..99dda0e38ba 100644 --- a/src/test/codegen-units/partitioning/methods-are-with-self-type.rs +++ b/src/test/codegen-units/partitioning/methods-are-with-self-type.rs @@ -61,19 +61,19 @@ mod type2 { //~ TRANS_ITEM fn methods_are_with_self_type::main[0] fn main() { - //~ TRANS_ITEM fn methods_are_with_self_type::mod1[0]::{{impl}}[1]::method[0] @@ methods_are_with_self_type.volatile[WeakODR] methods_are_with_self_type[Declaration] + //~ TRANS_ITEM fn methods_are_with_self_type::mod1[0]::{{impl}}[1]::method[0] @@ methods_are_with_self_type.volatile[WeakODR] SomeGenericType(0u32, 0u64).method(); - //~ TRANS_ITEM fn methods_are_with_self_type::mod1[0]::{{impl}}[1]::associated_fn[0] @@ methods_are_with_self_type.volatile[WeakODR] methods_are_with_self_type[Declaration] + //~ TRANS_ITEM fn methods_are_with_self_type::mod1[0]::{{impl}}[1]::associated_fn[0] @@ methods_are_with_self_type.volatile[WeakODR] SomeGenericType::associated_fn('c', "&str"); - //~ TRANS_ITEM fn methods_are_with_self_type::{{impl}}[0]::foo[0] @@ methods_are_with_self_type-type1.volatile[WeakODR] methods_are_with_self_type[Declaration] + //~ TRANS_ITEM fn methods_are_with_self_type::{{impl}}[0]::foo[0] @@ methods_are_with_self_type-type1.volatile[WeakODR] type1::Struct.foo(); - //~ TRANS_ITEM fn methods_are_with_self_type::{{impl}}[0]::foo[0] @@ methods_are_with_self_type-type2.volatile[WeakODR] methods_are_with_self_type[Declaration] + //~ TRANS_ITEM fn methods_are_with_self_type::{{impl}}[0]::foo[0] @@ methods_are_with_self_type-type2.volatile[WeakODR] type2::Struct.foo(); - //~ TRANS_ITEM fn methods_are_with_self_type::Trait[0]::default[0] @@ methods_are_with_self_type-type1.volatile[WeakODR] methods_are_with_self_type[Declaration] + //~ TRANS_ITEM fn methods_are_with_self_type::Trait[0]::default[0] @@ methods_are_with_self_type-type1.volatile[WeakODR] type1::Struct.default(); - //~ TRANS_ITEM fn methods_are_with_self_type::Trait[0]::default[0] @@ methods_are_with_self_type-type2.volatile[WeakODR] methods_are_with_self_type[Declaration] + //~ TRANS_ITEM fn methods_are_with_self_type::Trait[0]::default[0] @@ methods_are_with_self_type-type2.volatile[WeakODR] type2::Struct.default(); } -- cgit 1.4.1-3-g733a5 From f4dd4be86a9d8310608ee1ae84d33854cce52825 Mon Sep 17 00:00:00 2001 From: James Miller Date: Tue, 10 May 2016 10:14:41 +1200 Subject: Add test for collecting items in statics --- src/librustc_trans/collector.rs | 7 +++---- .../codegen-units/item-collection/static-init.rs | 23 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 src/test/codegen-units/item-collection/static-init.rs (limited to 'src/test') diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index f23f931d753..3675bf4b8ce 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -213,7 +213,6 @@ use meth; use monomorphize::{self, Instance}; use util::nodemap::{FnvHashSet, FnvHashMap, DefIdMap}; -use std::hash::{Hash, Hasher}; use trans_item::{TransItem, type_to_string, def_id_to_string}; #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] @@ -346,12 +345,12 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>, // Scan the MIR in order to find function calls, closures, and // drop-glue - let mir = errors::expect(ccx.sess().diagnostic(), ccx.get_mir(def_id), + let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(def_id), || format!("Could not find MIR for static: {:?}", def_id)); - let empty_substs = ccx.tcx().mk_substs(Substs::empty()); + let empty_substs = scx.tcx().mk_substs(Substs::empty()); let mut visitor = MirNeighborCollector { - ccx: ccx, + scx: scx, mir: &mir, output: &mut neighbors, param_substs: empty_substs diff --git a/src/test/codegen-units/item-collection/static-init.rs b/src/test/codegen-units/item-collection/static-init.rs new file mode 100644 index 00000000000..41c0f46f80b --- /dev/null +++ b/src/test/codegen-units/item-collection/static-init.rs @@ -0,0 +1,23 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags:-Zprint-trans-items=eager + +pub static FN : fn() = foo::; + +pub fn foo() { } + +//~ TRANS_ITEM fn static_init::foo[0] +//~ TRANS_ITEM static static_init::FN[0] + +fn main() { } + +//~ TRANS_ITEM fn static_init::main[0] +//~ TRANS_ITEM drop-glue i8 -- cgit 1.4.1-3-g733a5 From 64bc3c266cf97e2050bcf3a8565c48a60ca1a762 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 10 May 2016 17:24:44 -0400 Subject: trans: Make collector handle the drop_in_place() intrinsic. --- src/librustc_trans/collector.rs | 51 ++++++++++++++++++++-- .../item-collection/drop_in_place_intrinsic.rs | 41 +++++++++++++++++ 2 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs (limited to 'src/test') diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 3675bf4b8ce..7a04e45895c 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -202,9 +202,9 @@ use rustc::mir::repr as mir; use rustc::mir::visit as mir_visit; use rustc::mir::visit::Visitor as MirVisitor; +use syntax::abi::Abi; use syntax::codemap::DUMMY_SP; use syntax::errors; - use base::custom_coerce_unsize_info; use context::SharedCrateContext; use common::{fulfill_obligation, normalize_and_test_predicates, type_is_sized}; @@ -602,6 +602,49 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { can_have_local_instance(tcx, def_id) } } + + // This takes care of the "drop_in_place" intrinsic for which we otherwise + // we would not register drop-glues. + fn visit_terminator_kind(&mut self, + block: mir::BasicBlock, + kind: &mir::TerminatorKind<'tcx>) { + let tcx = self.scx.tcx(); + match *kind { + mir::TerminatorKind::Call { + func: mir::Operand::Constant(ref constant), + ref args, + .. + } => { + match constant.ty.sty { + ty::TyFnDef(def_id, _, bare_fn_ty) + if is_drop_in_place_intrinsic(tcx, def_id, bare_fn_ty) => { + let operand_ty = self.mir.operand_ty(tcx, &args[0]); + if let ty::TyRawPtr(mt) = operand_ty.sty { + let operand_ty = monomorphize::apply_param_substs(tcx, + self.param_substs, + &mt.ty); + self.output.push(TransItem::DropGlue(DropGlueKind::Ty(operand_ty))); + } else { + bug!("Has the drop_in_place() intrinsic's signature changed?") + } + } + _ => { /* Nothing to do. */ } + } + } + _ => { /* Nothing to do. */ } + } + + self.super_terminator_kind(block, kind); + + fn is_drop_in_place_intrinsic<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + def_id: DefId, + bare_fn_ty: &ty::BareFnTy<'tcx>) + -> bool { + (bare_fn_ty.abi == Abi::RustIntrinsic || + bare_fn_ty.abi == Abi::PlatformIntrinsic) && + tcx.item_name(def_id).as_str() == "drop_in_place" + } + } } fn can_have_local_instance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -699,7 +742,6 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, ty::TyRef(..) | ty::TyFnDef(..) | ty::TyFnPtr(_) | - ty::TySlice(_) | ty::TyTrait(_) => { /* nothing to do */ } @@ -725,6 +767,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, } } ty::TyBox(inner_type) | + ty::TySlice(inner_type) | ty::TyArray(inner_type, _) => { let inner_type = glue::get_drop_glue_type(scx.tcx(), inner_type); if glue::type_needs_drop(scx.tcx(), inner_type) { @@ -746,6 +789,8 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, bug!("encountered unexpected type"); } } + + } fn do_static_dispatch<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, @@ -1187,7 +1232,7 @@ pub enum TransItemState { } pub fn collecting_debug_information(scx: &SharedCrateContext) -> bool { - return cfg!(debug_assertions) && + return scx.sess().opts.cg.debug_assertions == Some(true) && scx.sess().opts.debugging_opts.print_trans_items.is_some(); } diff --git a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs new file mode 100644 index 00000000000..db940b68047 --- /dev/null +++ b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs @@ -0,0 +1,41 @@ +// Copyright 2012-2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-tidy-linelength +// compile-flags:-Zprint-trans-items=eager + +//~ TRANS_ITEM drop-glue drop_in_place_intrinsic::StructWithDtor[0] +//~ TRANS_ITEM drop-glue-contents drop_in_place_intrinsic::StructWithDtor[0] +struct StructWithDtor(u32); + +impl Drop for StructWithDtor { + //~ TRANS_ITEM fn drop_in_place_intrinsic::{{impl}}[0]::drop[0] + fn drop(&mut self) {} +} + +//~ TRANS_ITEM fn drop_in_place_intrinsic::main[0] +fn main() { + + //~ TRANS_ITEM drop-glue [drop_in_place_intrinsic::StructWithDtor[0]; 2] + let x = [StructWithDtor(0), StructWithDtor(1)]; + + drop_slice_in_place(&x); +} + +//~ TRANS_ITEM fn drop_in_place_intrinsic::drop_slice_in_place[0] +fn drop_slice_in_place(x: &[StructWithDtor]) { + unsafe { + // This is the interesting thing in this test case: Normally we would + // not have drop-glue for the unsized [StructWithDtor]. This has to be + // generated though when the drop_in_place() intrinsic is used. + //~ TRANS_ITEM drop-glue [drop_in_place_intrinsic::StructWithDtor[0]] + ::std::ptr::drop_in_place(x as *const _ as *mut [StructWithDtor]); + } +} -- cgit 1.4.1-3-g733a5 From d3218fae7b5a4a0ba9b02903dc12d36ff94a1388 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Thu, 12 May 2016 00:48:47 +0300 Subject: Check the constants’ parameter environment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/librustc_typeck/check/mod.rs | 3 ++- src/test/run-pass/associated-const-outer-ty-refs.rs | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/associated-const-outer-ty-refs.rs (limited to 'src/test') diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f428023da9b..648d1f94e62 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1151,7 +1151,8 @@ fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, sp: Span, e: &'tcx hir::Expr, id: ast::NodeId) { - ccx.inherited(None).enter(|inh| { + let param_env = ParameterEnvironment::for_item(ccx.tcx, id); + ccx.inherited(Some(param_env)).enter(|inh| { let rty = ccx.tcx.node_id_to_type(id); let fcx = FnCtxt::new(&inh, ty::FnConverging(rty), e.id); let declty = fcx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty; diff --git a/src/test/run-pass/associated-const-outer-ty-refs.rs b/src/test/run-pass/associated-const-outer-ty-refs.rs new file mode 100644 index 00000000000..a603b225132 --- /dev/null +++ b/src/test/run-pass/associated-const-outer-ty-refs.rs @@ -0,0 +1,21 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +#![feature(associated_consts)] + +trait Lattice { + const BOTTOM: Self; +} + +// FIXME(#33573): this should work without the 'static lifetime bound. +impl Lattice for Option { + const BOTTOM: Option = None; +} + +fn main(){} -- cgit 1.4.1-3-g733a5 From 9393e52d4d2705698a6dfdd2834d41154ee23b64 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 8 May 2016 12:07:50 -0700 Subject: Don't use env::current_exe with libbacktrace If the path we give to libbacktrace doesn't actually correspond to the current process, libbacktrace will segfault *at best*. cc #21889 --- src/libstd/sys/common/gnu/libbacktrace.rs | 49 ++++++++----------------------- src/test/run-pass/backtrace-debuginfo.rs | 14 +++++---- src/test/run-pass/backtrace.rs | 2 +- 3 files changed, 22 insertions(+), 43 deletions(-) (limited to 'src/test') diff --git a/src/libstd/sys/common/gnu/libbacktrace.rs b/src/libstd/sys/common/gnu/libbacktrace.rs index db719ccce61..b5802afc109 100644 --- a/src/libstd/sys/common/gnu/libbacktrace.rs +++ b/src/libstd/sys/common/gnu/libbacktrace.rs @@ -15,7 +15,6 @@ use sys_common::backtrace::{output, output_fileline}; pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void, symaddr: *mut libc::c_void) -> io::Result<()> { - use env; use ffi::CStr; use ptr; @@ -110,46 +109,22 @@ pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void, // that is calculated the first time this is requested. Remember that // backtracing all happens serially (one global lock). // - // An additionally oddity in this function is that we initialize the - // filename via self_exe_name() to pass to libbacktrace. It turns out - // that on Linux libbacktrace seamlessly gets the filename of the - // current executable, but this fails on freebsd. by always providing - // it, we make sure that libbacktrace never has a reason to not look up - // the symbols. The libbacktrace API also states that the filename must - // be in "permanent memory", so we copy it to a static and then use the - // static as the pointer. + // Things don't work so well on not-Linux since libbacktrace can't track + // down that executable this is. We at one point used env::current_exe but + // it turns out that there are some serious security issues with that + // approach. // - // FIXME: We also call self_exe_name() on DragonFly BSD. I haven't - // tested if this is required or not. + // Specifically, on certain platforms like BSDs, a malicious actor can cause + // an arbitrary file to be placed at the path returned by current_exe. + // libbacktrace does not behave defensively in the presence of ill-formed + // DWARF information, and has been demonstrated to segfault in at least one + // case. There is no evidence at the moment to suggest that a more carefully + // constructed file can't cause arbitrary code execution. As a result of all + // of this, we don't hint libbacktrace with the path to the current process. unsafe fn init_state() -> *mut backtrace_state { static mut STATE: *mut backtrace_state = ptr::null_mut(); - static mut LAST_FILENAME: [libc::c_char; 256] = [0; 256]; if !STATE.is_null() { return STATE } - let selfname = if cfg!(target_os = "freebsd") || - cfg!(target_os = "dragonfly") || - cfg!(target_os = "bitrig") || - cfg!(target_os = "openbsd") || - cfg!(target_os = "windows") { - env::current_exe().ok() - } else { - None - }; - let filename = match selfname.as_ref().and_then(|s| s.to_str()) { - Some(path) => { - let bytes = path.as_bytes(); - if bytes.len() < LAST_FILENAME.len() { - let i = bytes.iter(); - for (slot, val) in LAST_FILENAME.iter_mut().zip(i) { - *slot = *val as libc::c_char; - } - LAST_FILENAME.as_ptr() - } else { - ptr::null() - } - } - None => ptr::null(), - }; - STATE = backtrace_create_state(filename, 0, error_cb, + STATE = backtrace_create_state(ptr::null(), 0, error_cb, ptr::null_mut()); STATE } diff --git a/src/test/run-pass/backtrace-debuginfo.rs b/src/test/run-pass/backtrace-debuginfo.rs index 8b2b2694882..f42a6ab162b 100644 --- a/src/test/run-pass/backtrace-debuginfo.rs +++ b/src/test/run-pass/backtrace-debuginfo.rs @@ -32,11 +32,15 @@ macro_rules! dump_and_die { ($($pos:expr),*) => ({ // FIXME(#18285): we cannot include the current position because // the macro span takes over the last frame's file/line. - if cfg!(target_os = "macos") || - cfg!(target_os = "ios") || - cfg!(target_os = "android") || - cfg!(all(target_os = "linux", target_arch = "arm")) || - cfg!(all(windows, target_env = "gnu")) { + if cfg!(any(target_os = "macos", + target_os = "ios", + target_os = "android", + all(target_os = "linux", target_arch = "arm"), + target_os = "windows", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "bitrig", + target_os = "openbsd")) { // skip these platforms as this support isn't implemented yet. } else { dump_filelines(&[$($pos),*]); diff --git a/src/test/run-pass/backtrace.rs b/src/test/run-pass/backtrace.rs index 5b364358a59..ad38dc8f452 100644 --- a/src/test/run-pass/backtrace.rs +++ b/src/test/run-pass/backtrace.rs @@ -115,7 +115,7 @@ fn runtest(me: &str) { } fn main() { - if cfg!(windows) && cfg!(target_arch = "x86") && cfg!(target_env = "gnu") { + if cfg!(windows) && cfg!(target_env = "gnu") { return } -- cgit 1.4.1-3-g733a5