diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 47e8588857d6a..e01222747589d 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -166,7 +166,14 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> { hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) | hir::ItemKind::Existential(..) | hir::ItemKind::Ty(..) | hir::ItemKind::Union(..) | hir::ItemKind::Use(..) => { - if item.vis.node.is_pub() { self.prev_level } else { None } + // `#[export_name]` and `#[no_mangle]` items are at least Reachable + if item.attrs.iter().any(|attr| { + attr.check_name("export_name") || attr.check_name("no_mangle") + }) { + cmp::max(Some(AccessLevel::Reachable), self.prev_level) + } else { + if item.vis.node.is_pub() { self.prev_level } else { None } + } } }; diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 6eb2db8e63bfe..b7418d9bc2c13 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -519,6 +519,9 @@ pub fn update_count_then_panic(msg: Box) -> ! { /// A private no-mangle function on which to slap yer breakpoints. #[no_mangle] #[allow(private_no_mangle_fns)] // yes we get it, but we like breakpoints +#[unstable(feature = "libstd_sys_internals", + reason = "used by the panic! macro", + issue = "0")] pub fn rust_panic(mut msg: &mut dyn BoxMeUp) -> ! { let code = unsafe { let obj = &mut msg as *mut &mut dyn BoxMeUp; diff --git a/src/test/codegen/external-no-mangle-fns.rs b/src/test/codegen/external-no-mangle-fns.rs new file mode 100644 index 0000000000000..3f092b802f99a --- /dev/null +++ b/src/test/codegen/external-no-mangle-fns.rs @@ -0,0 +1,63 @@ +// Copyright 2018 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: -O +// `#[no_mangle]`d functions always have external linkage, i.e. no `internal` in their `define`s + +#![crate_type = "lib"] +#![no_std] + +// CHECK: define void @a() +#[no_mangle] +fn a() {} + +// CHECK: define void @b() +#[no_mangle] +pub fn b() {} + +mod private { + // CHECK: define void @c() + #[no_mangle] + fn c() {} + + // CHECK: define void @d() + #[no_mangle] + pub fn d() {} +} + +const HIDDEN: () = { + // CHECK: define void @e() + #[no_mangle] + fn e() {} + + // CHECK: define void @f() + #[no_mangle] + pub fn f() {} +}; + +// The surrounding item should not accidentally become external +// CHECK: define internal {{.*}} void @_ZN22external_no_mangle_fns1x +#[inline(never)] +fn x() { + // CHECK: define void @g() + #[no_mangle] + fn g() { + x(); + } + + // CHECK: define void @h() + #[no_mangle] + pub fn h() {} + + // side effect to keep `x` around + unsafe { + core::ptr::read_volatile(&42); + } +} diff --git a/src/test/codegen/external-no-mangle-statics.rs b/src/test/codegen/external-no-mangle-statics.rs new file mode 100644 index 0000000000000..59d829633e55c --- /dev/null +++ b/src/test/codegen/external-no-mangle-statics.rs @@ -0,0 +1,88 @@ +// Copyright 2018 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: -O +// `#[no_mangle]`d static variables always have external linkage, i.e. no `internal` in their +// definitions + +#![crate_type = "lib"] +#![no_std] + +// CHECK: @A = local_unnamed_addr constant +#[no_mangle] +static A: u8 = 0; + +// CHECK: @B = local_unnamed_addr global +#[no_mangle] +static mut B: u8 = 0; + +// CHECK: @C = local_unnamed_addr constant +#[no_mangle] +pub static C: u8 = 0; + +// CHECK: @D = local_unnamed_addr global +#[no_mangle] +pub static mut D: u8 = 0; + +mod private { + // CHECK: @E = local_unnamed_addr constant + #[no_mangle] + static E: u8 = 0; + + // CHECK: @F = local_unnamed_addr global + #[no_mangle] + static mut F: u8 = 0; + + // CHECK: @G = local_unnamed_addr constant + #[no_mangle] + pub static G: u8 = 0; + + // CHECK: @H = local_unnamed_addr global + #[no_mangle] + pub static mut H: u8 = 0; +} + +const HIDDEN: () = { + // CHECK: @I = local_unnamed_addr constant + #[no_mangle] + static I: u8 = 0; + + // CHECK: @J = local_unnamed_addr global + #[no_mangle] + static mut J: u8 = 0; + + // CHECK: @K = local_unnamed_addr constant + #[no_mangle] + pub static K: u8 = 0; + + // CHECK: @L = local_unnamed_addr global + #[no_mangle] + pub static mut L: u8 = 0; +}; + +// The surrounding item should not accidentally become external +fn x() { + // CHECK: @M = local_unnamed_addr constant + #[no_mangle] + static M: fn() = x; + + // CHECK: @N = local_unnamed_addr global + #[no_mangle] + static mut N: u8 = 0; + + // CHECK: @O = local_unnamed_addr constant + #[no_mangle] + pub static O: u8 = 0; + + // CHECK: @P = local_unnamed_addr global + #[no_mangle] + pub static mut P: u8 = 0; +} +// CHECK: define internal void @_ZN26external_no_mangle_statics1x{{.*$}}