diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 904c9c3adb567..22f5ca150219b 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -2065,12 +2065,26 @@ declare_lint! { "functions marked #[no_mangle] should be exported" } +declare_lint! { + PRIVATE_NO_MANGLE_STATICS, + Warn, + "statics marked #[no_mangle] should be exported" +} + +declare_lint! { + NO_MANGLE_CONST_ITEMS, + Deny, + "const items will not have their symbols exported" +} + #[derive(Copy)] -pub struct PrivateNoMangleFns; +pub struct InvalidNoMangleItems; -impl LintPass for PrivateNoMangleFns { +impl LintPass for InvalidNoMangleItems { fn get_lints(&self) -> LintArray { - lint_array!(PRIVATE_NO_MANGLE_FNS) + lint_array!(PRIVATE_NO_MANGLE_FNS, + PRIVATE_NO_MANGLE_STATICS, + NO_MANGLE_CONST_ITEMS) } fn check_item(&mut self, cx: &Context, it: &ast::Item) { @@ -2083,6 +2097,23 @@ impl LintPass for PrivateNoMangleFns { cx.span_lint(PRIVATE_NO_MANGLE_FNS, it.span, msg.as_slice()); } }, + ast::ItemStatic(..) => { + if attr::contains_name(it.attrs.as_slice(), "no_mangle") && + !cx.exported_items.contains(&it.id) { + let msg = format!("static {} is marked #[no_mangle], but not exported", + it.ident); + cx.span_lint(PRIVATE_NO_MANGLE_STATICS, it.span, msg.as_slice()); + } + }, + ast::ItemConst(..) => { + if attr::contains_name(it.attrs.as_slice(), "no_mangle") { + // Const items do not refer to a particular location in memory, and therefore + // don't have anything to attach a symbol to + let msg = "const items should never be #[no_mangle], consider instead using \ + `pub static`"; + cx.span_lint(NO_MANGLE_CONST_ITEMS, it.span, msg); + } + } _ => {}, } } diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index c649ff2635bf0..730a125fe9724 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -213,7 +213,7 @@ impl LintStore { UnstableFeatures, Stability, UnconditionalRecursion, - PrivateNoMangleFns, + InvalidNoMangleItems, ); add_builtin_with_new!(sess, diff --git a/src/test/compile-fail/lint-unexported-no-mangle.rs b/src/test/compile-fail/lint-unexported-no-mangle.rs index 3227a78c2ef00..216fcf9353578 100644 --- a/src/test/compile-fail/lint-unexported-no-mangle.rs +++ b/src/test/compile-fail/lint-unexported-no-mangle.rs @@ -8,17 +8,32 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags:-F private_no_mangle_fns +// compile-flags:-F private_no_mangle_fns -F no_mangle_const_items -F private_no_mangle_statics // FIXME(#19495) no_mangle'ing main ICE's. #[no_mangle] fn foo() { //~ ERROR function foo is marked #[no_mangle], but not exported } +#[allow(dead_code)] +#[no_mangle] +const FOO: u64 = 1; //~ ERROR const items should never be #[no_mangle] + +#[no_mangle] +pub const PUB_FOO: u64 = 1; //~ ERROR const items should never be #[no_mangle] + #[no_mangle] pub fn bar() { } +#[no_mangle] +pub static BAR: u64 = 1; + +#[allow(dead_code)] +#[no_mangle] +static PRIVATE_BAR: u64 = 1; //~ ERROR static PRIVATE_BAR is marked #[no_mangle], but not exported + + fn main() { foo(); bar();