diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index e594d462ff3..4e2ab82cd4e 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -2037,6 +2037,35 @@ impl LintPass for HardwiredLints { } } +declare_lint! { + PRIVATE_NO_MANGLE_FNS, + Warn, + "functions marked #[no_mangle] should be exported" +} + +#[derive(Copy)] +pub struct PrivateNoMangleFns; + +impl LintPass for PrivateNoMangleFns { + fn get_lints(&self) -> LintArray { + lint_array!(PRIVATE_NO_MANGLE_FNS) + } + + fn check_item(&mut self, cx: &Context, it: &ast::Item) { + match it.node { + ast::ItemFn(..) => { + if attr::contains_name(it.attrs.as_slice(), "no_mangle") && + !cx.exported_items.contains(&it.id) { + let msg = format!("function {} is marked #[no_mangle], but not exported", + it.ident); + cx.span_lint(PRIVATE_NO_MANGLE_FNS, it.span, msg.as_slice()); + } + }, + _ => {}, + } + } +} + /// Forbids using the `#[feature(...)]` attribute #[derive(Copy)] pub struct UnstableFeatures; diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index f57d7956edf..76f874f2428 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -213,6 +213,7 @@ impl LintStore { UnstableFeatures, Stability, UnconditionalRecursion, + PrivateNoMangleFns, ); add_builtin_with_new!(sess, diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs index 18298f1c7f4..757aecaaaff 100644 --- a/src/libstd/rt/unwind.rs +++ b/src/libstd/rt/unwind.rs @@ -160,6 +160,7 @@ pub fn panicking() -> bool { // An uninlined, unmangled function upon which to slap yer breakpoints #[inline(never)] #[no_mangle] +#[allow(private_no_mangle_fns)] fn rust_panic(cause: Box) -> ! { rtdebug!("begin_unwind()"); @@ -237,6 +238,7 @@ pub mod eabi { #[lang="eh_personality"] #[no_mangle] // referenced from rust_try.ll + #[allow(private_no_mangle_fns)] extern fn rust_eh_personality( version: c_int, actions: uw::_Unwind_Action, @@ -290,6 +292,7 @@ pub mod eabi { #[lang="eh_personality"] #[no_mangle] // referenced from rust_try.ll + #[allow(private_no_mangle_fns)] pub extern "C" fn rust_eh_personality( version: c_int, actions: uw::_Unwind_Action, @@ -343,6 +346,7 @@ pub mod eabi { #[lang="eh_personality"] #[no_mangle] // referenced from rust_try.ll + #[allow(private_no_mangle_fns)] extern "C" fn rust_eh_personality( state: uw::_Unwind_State, ue_header: *mut uw::_Unwind_Exception, @@ -432,6 +436,7 @@ pub mod eabi { #[lang="eh_personality"] #[no_mangle] // referenced from rust_try.ll + #[allow(private_no_mangle_fns)] extern "C" fn rust_eh_personality( exceptionRecord: *mut EXCEPTION_RECORD, establisherFrame: *mut c_void, diff --git a/src/test/compile-fail/lint-unexported-no-mangle.rs b/src/test/compile-fail/lint-unexported-no-mangle.rs new file mode 100644 index 00000000000..3227a78c2ef --- /dev/null +++ b/src/test/compile-fail/lint-unexported-no-mangle.rs @@ -0,0 +1,25 @@ +// Copyright 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. + +// compile-flags:-F private_no_mangle_fns + +// FIXME(#19495) no_mangle'ing main ICE's. +#[no_mangle] +fn foo() { //~ ERROR function foo is marked #[no_mangle], but not exported +} + +#[no_mangle] +pub fn bar() { +} + +fn main() { + foo(); + bar(); +}