diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index ea624b9ed3003..d768775e0cf39 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -236,6 +236,18 @@ impl UnsafeCode { cx.struct_span_lint(UNSAFE_CODE, span, decorate); } + + fn report_overriden_symbol_name(&self, cx: &EarlyContext<'_>, span: Span, msg: &str) { + self.report_unsafe(cx, span, |lint| { + lint.build(msg) + .note( + "the linker's behavior with multiple libraries exporting duplicate symbol \ + names is undefined and Rust cannot provide guarantees when you manually \ + override them", + ) + .emit(); + }) + } } impl EarlyLintPass for UnsafeCode { @@ -277,6 +289,40 @@ impl EarlyLintPass for UnsafeCode { }) } + ast::ItemKind::Fn(..) => { + if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::no_mangle) { + self.report_overriden_symbol_name( + cx, + attr.span, + "declaration of a `no_mangle` function", + ); + } + if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::export_name) { + self.report_overriden_symbol_name( + cx, + attr.span, + "declaration of a function with `export_name`", + ); + } + } + + ast::ItemKind::Static(..) => { + if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::no_mangle) { + self.report_overriden_symbol_name( + cx, + attr.span, + "declaration of a `no_mangle` static", + ); + } + if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::export_name) { + self.report_overriden_symbol_name( + cx, + attr.span, + "declaration of a static with `export_name`", + ); + } + } + _ => {} } } diff --git a/src/test/ui/lint/lint-unsafe-code.rs b/src/test/ui/lint/lint-unsafe-code.rs index 735f33f601f9d..4ac02b51f62fe 100644 --- a/src/test/ui/lint/lint-unsafe-code.rs +++ b/src/test/ui/lint/lint-unsafe-code.rs @@ -12,14 +12,28 @@ mod allowed_unsafe { unsafe fn also_allowed() {} unsafe trait AllowedUnsafe { } unsafe impl AllowedUnsafe for super::Bar {} + #[no_mangle] fn allowed2() {} + #[export_name = "foo"] fn allowed3() {} } macro_rules! unsafe_in_macro { - () => { + () => {{ + #[no_mangle] fn foo() {} //~ ERROR: declaration of a `no_mangle` function + #[no_mangle] static FOO: u32 = 5; //~ ERROR: declaration of a `no_mangle` static + #[export_name = "bar"] fn bar() {} + //~^ ERROR: declaration of a function with `export_name` + #[export_name = "BAR"] static BAR: u32 = 5; + //~^ ERROR: declaration of a static with `export_name` unsafe {} //~ ERROR: usage of an `unsafe` block - } + }} } +#[no_mangle] fn foo() {} //~ ERROR: declaration of a `no_mangle` function +#[no_mangle] static FOO: u32 = 5; //~ ERROR: declaration of a `no_mangle` static + +#[export_name = "bar"] fn bar() {} //~ ERROR: declaration of a function with `export_name` +#[export_name = "BAR"] static BAR: u32 = 5; //~ ERROR: declaration of a static with `export_name` + unsafe fn baz() {} //~ ERROR: declaration of an `unsafe` function unsafe trait Foo {} //~ ERROR: declaration of an `unsafe` trait unsafe impl Foo for Bar {} //~ ERROR: implementation of an `unsafe` trait diff --git a/src/test/ui/lint/lint-unsafe-code.stderr b/src/test/ui/lint/lint-unsafe-code.stderr index 0b2b9fab3925e..a8ef047e517b4 100644 --- a/src/test/ui/lint/lint-unsafe-code.stderr +++ b/src/test/ui/lint/lint-unsafe-code.stderr @@ -1,89 +1,168 @@ -error: declaration of an `unsafe` function - --> $DIR/lint-unsafe-code.rs:23:1 +error: declaration of a `no_mangle` function + --> $DIR/lint-unsafe-code.rs:31:1 | -LL | unsafe fn baz() {} - | ^^^^^^^^^^^^^^^^^^ +LL | #[no_mangle] fn foo() {} + | ^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/lint-unsafe-code.rs:3:9 | LL | #![deny(unsafe_code)] | ^^^^^^^^^^^ + = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them + +error: declaration of a `no_mangle` static + --> $DIR/lint-unsafe-code.rs:32:1 + | +LL | #[no_mangle] static FOO: u32 = 5; + | ^^^^^^^^^^^^ + | + = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them + +error: declaration of a function with `export_name` + --> $DIR/lint-unsafe-code.rs:34:1 + | +LL | #[export_name = "bar"] fn bar() {} + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them + +error: declaration of a static with `export_name` + --> $DIR/lint-unsafe-code.rs:35:1 + | +LL | #[export_name = "BAR"] static BAR: u32 = 5; + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them + +error: declaration of an `unsafe` function + --> $DIR/lint-unsafe-code.rs:37:1 + | +LL | unsafe fn baz() {} + | ^^^^^^^^^^^^^^^^^^ error: declaration of an `unsafe` trait - --> $DIR/lint-unsafe-code.rs:24:1 + --> $DIR/lint-unsafe-code.rs:38:1 | LL | unsafe trait Foo {} | ^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` trait - --> $DIR/lint-unsafe-code.rs:25:1 + --> $DIR/lint-unsafe-code.rs:39:1 | LL | unsafe impl Foo for Bar {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: declaration of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:28:5 + --> $DIR/lint-unsafe-code.rs:42:5 | LL | unsafe fn baz(&self); | ^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:29:5 + --> $DIR/lint-unsafe-code.rs:43:5 | LL | unsafe fn provided(&self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:30:5 + --> $DIR/lint-unsafe-code.rs:44:5 | LL | unsafe fn provided_override(&self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:34:5 + --> $DIR/lint-unsafe-code.rs:48:5 | LL | unsafe fn baz(&self) {} | ^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:35:5 + --> $DIR/lint-unsafe-code.rs:49:5 | LL | unsafe fn provided_override(&self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:54:5 + --> $DIR/lint-unsafe-code.rs:68:5 | LL | unsafe fn provided_override(&self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:65:5 + --> $DIR/lint-unsafe-code.rs:79:5 | LL | unsafe fn provided(&self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:71:5 + --> $DIR/lint-unsafe-code.rs:85:5 | LL | unsafe fn provided(&self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:75:5 + --> $DIR/lint-unsafe-code.rs:89:5 | LL | unsafe fn baz(&self) {} | ^^^^^^^^^^^^^^^^^^^^^^^ error: usage of an `unsafe` block - --> $DIR/lint-unsafe-code.rs:86:5 + --> $DIR/lint-unsafe-code.rs:100:5 | LL | unsafe {} | ^^^^^^^^^ +error: declaration of a `no_mangle` function + --> $DIR/lint-unsafe-code.rs:21:9 + | +LL | #[no_mangle] fn foo() {} + | ^^^^^^^^^^^^ +... +LL | unsafe_in_macro!() + | ------------------ in this macro invocation + | + = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: declaration of a `no_mangle` static + --> $DIR/lint-unsafe-code.rs:22:9 + | +LL | #[no_mangle] static FOO: u32 = 5; + | ^^^^^^^^^^^^ +... +LL | unsafe_in_macro!() + | ------------------ in this macro invocation + | + = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: declaration of a function with `export_name` + --> $DIR/lint-unsafe-code.rs:23:9 + | +LL | #[export_name = "bar"] fn bar() {} + | ^^^^^^^^^^^^^^^^^^^^^^ +... +LL | unsafe_in_macro!() + | ------------------ in this macro invocation + | + = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: declaration of a static with `export_name` + --> $DIR/lint-unsafe-code.rs:25:9 + | +LL | #[export_name = "BAR"] static BAR: u32 = 5; + | ^^^^^^^^^^^^^^^^^^^^^^ +... +LL | unsafe_in_macro!() + | ------------------ in this macro invocation + | + = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + error: usage of an `unsafe` block - --> $DIR/lint-unsafe-code.rs:19:9 + --> $DIR/lint-unsafe-code.rs:27:9 | LL | unsafe {} | ^^^^^^^^^ @@ -93,5 +172,5 @@ LL | unsafe_in_macro!() | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 14 previous errors +error: aborting due to 22 previous errors