about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2021-02-09 02:39:45 +0100
committerGitHub <noreply@github.com>2021-02-09 02:39:45 +0100
commitf8b330d9fb114132fb41eccdafbe29b48d386749 (patch)
tree6f5d45ca70867fe5af9d2eadd0f93f70c969f9e0
parent0fc6756b42e0556cc2e18079f5fc6b4d58f4e81a (diff)
parentfc8a3ad66c7026e782ee54bd3849cc860983b69a (diff)
downloadrust-f8b330d9fb114132fb41eccdafbe29b48d386749.tar.gz
rust-f8b330d9fb114132fb41eccdafbe29b48d386749.zip
Rollup merge of #72209 - Nemo157:lint-no-mangle-in-unsafe-code, r=nikomatsakis
Add checking for no_mangle to unsafe_code lint

fixes #72188

r? `@estebank`
-rw-r--r--compiler/rustc_lint/src/builtin.rs46
-rw-r--r--src/test/ui/lint/lint-unsafe-code.rs18
-rw-r--r--src/test/ui/lint/lint-unsafe-code.stderr115
3 files changed, 159 insertions, 20 deletions
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 2cedef62519..20f581625dc 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -328,6 +328,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 {
@@ -367,6 +379,40 @@ impl EarlyLintPass for UnsafeCode {
                     lint.build("implementation of an `unsafe` trait").emit()
                 }),
 
+            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 735f33f601f..4ac02b51f62 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 0b2b9fab392..a8ef047e517 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