Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emit specific warning to clarify that #[no_mangle] should not be applied on foreign statics or functions #86376

Merged
merged 1 commit into from
Sep 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1331,6 +1331,36 @@ impl CheckAttrVisitor<'tcx> {
Target::Field | Target::Arm | Target::MacroDef => {
self.inline_attr_str_error_with_macro_def(hir_id, attr, "no_mangle");
}
// FIXME: #[no_mangle] was previously allowed on non-functions/statics, this should be an error
// The error should specify that the item that is wrong is specifically a *foreign* fn/static
// otherwise the error seems odd
Target::ForeignFn | Target::ForeignStatic => {
let foreign_item_kind = match target {
Target::ForeignFn => "function",
Target::ForeignStatic => "static",
_ => unreachable!(),
};
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
lint.build(&format!(
"`#[no_mangle]` has no effect on a foreign {}",
foreign_item_kind
))
.warn(
"this was previously accepted by the compiler but is \
being phased out; it will become a hard error in \
a future release!",
)
.span_label(*span, format!("foreign {}", foreign_item_kind))
.note("symbol names in extern blocks are not mangled")
.span_suggestion(
attr.span,
"remove this attribute",
String::new(),
Applicability::MachineApplicable,
)
.emit();
});
}
_ => {
// FIXME: #[no_mangle] was previously allowed on non-functions/statics and some
// crates used this, so only emit a warning.
Expand Down
30 changes: 30 additions & 0 deletions src/test/ui/extern/extern-no-mangle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#![warn(unused_attributes)]

// Tests that placing the #[no_mangle] attribute on a foreign fn or static emits
// a specialized warning.
// The previous warning only talks about a "function or static" but foreign fns/statics
// are also not allowed to have #[no_mangle]

// build-pass

extern "C" {
#[no_mangle]
//~^ WARNING `#[no_mangle]` has no effect on a foreign static
//~^^ WARNING this was previously accepted by the compiler
pub static FOO: u8;

#[no_mangle]
//~^ WARNING `#[no_mangle]` has no effect on a foreign function
//~^^ WARNING this was previously accepted by the compiler
pub fn bar();
}

fn no_new_warn() {
// Should emit the generic "not a function or static" warning
#[no_mangle]
//~^ WARNING attribute should be applied to a free function, impl method or static
//~^^ WARNING this was previously accepted by the compiler
let x = 0_u8;
}

fn main() {}
42 changes: 42 additions & 0 deletions src/test/ui/extern/extern-no-mangle.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
warning: attribute should be applied to a free function, impl method or static
--> $DIR/extern-no-mangle.rs:24:5
|
LL | #[no_mangle]
| ^^^^^^^^^^^^
...
LL | let x = 0_u8;
| ------------- not a free function, impl method or static
|
note: the lint level is defined here
--> $DIR/extern-no-mangle.rs:1:9
|
LL | #![warn(unused_attributes)]
| ^^^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!

warning: `#[no_mangle]` has no effect on a foreign static
--> $DIR/extern-no-mangle.rs:11:5
|
LL | #[no_mangle]
| ^^^^^^^^^^^^ help: remove this attribute
...
LL | pub static FOO: u8;
| ------------------- foreign static
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: symbol names in extern blocks are not mangled

warning: `#[no_mangle]` has no effect on a foreign function
--> $DIR/extern-no-mangle.rs:16:5
|
LL | #[no_mangle]
| ^^^^^^^^^^^^ help: remove this attribute
...
LL | pub fn bar();
| ------------- foreign function
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: symbol names in extern blocks are not mangled

warning: 3 warnings emitted