about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/lint/builtin.rs29
-rw-r--r--src/librustc/lint/context.rs1
-rw-r--r--src/libstd/rt/unwind.rs5
-rw-r--r--src/test/compile-fail/lint-unexported-no-mangle.rs25
4 files changed, 60 insertions, 0 deletions
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index ee7c0ee894f..ae537e557e7 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<Any + Send>) -> ! {
     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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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();
+}