Auto merge of #13631 - samueltardieu:push-uoowutzkvsrk, r=Centri3
no_mangle attribute requires unsafe in Rust 2024 Tests without unsafe must not run in edition 2024. Also, error messages have been modified to include the full attribute, so that a use of `#[unsafe(no_mangle)]` does not produce an error message containing `#[no_mangle]`. changelog: [`no_mangle_attribute`]: handle `#[unsafe(no_mangle)]` as well
This commit is contained in:
commit
a1a9aaef87
@ -1,5 +1,5 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::source::snippet_with_applicability;
|
use clippy_utils::source::{snippet, snippet_with_applicability};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Item, ItemKind};
|
use rustc_hir::{Item, ItemKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
@ -18,13 +18,13 @@ declare_clippy_lint! {
|
|||||||
/// Rust ABI can break this at any point.
|
/// Rust ABI can break this at any point.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```no_run
|
/// ```rust,ignore
|
||||||
/// #[no_mangle]
|
/// #[no_mangle]
|
||||||
/// fn example(arg_one: u32, arg_two: usize) {}
|
/// fn example(arg_one: u32, arg_two: usize) {}
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```no_run
|
/// ```rust,ignore
|
||||||
/// #[no_mangle]
|
/// #[no_mangle]
|
||||||
/// extern "C" fn example(arg_one: u32, arg_two: usize) {}
|
/// extern "C" fn example(arg_one: u32, arg_two: usize) {}
|
||||||
/// ```
|
/// ```
|
||||||
@ -40,24 +40,25 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi {
|
|||||||
if let ItemKind::Fn(fn_sig, _, _) = &item.kind {
|
if let ItemKind::Fn(fn_sig, _, _) = &item.kind {
|
||||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||||
let mut app = Applicability::MaybeIncorrect;
|
let mut app = Applicability::MaybeIncorrect;
|
||||||
let snippet = snippet_with_applicability(cx, fn_sig.span, "..", &mut app);
|
let fn_snippet = snippet_with_applicability(cx, fn_sig.span, "..", &mut app);
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
if let Some(ident) = attr.ident()
|
if let Some(ident) = attr.ident()
|
||||||
&& ident.name == rustc_span::sym::no_mangle
|
&& ident.name == rustc_span::sym::no_mangle
|
||||||
&& fn_sig.header.abi == Abi::Rust
|
&& fn_sig.header.abi == Abi::Rust
|
||||||
&& let Some((fn_attrs, _)) = snippet.split_once("fn")
|
&& let Some((fn_attrs, _)) = fn_snippet.split_once("fn")
|
||||||
&& !fn_attrs.contains("extern")
|
&& !fn_attrs.contains("extern")
|
||||||
{
|
{
|
||||||
let sugg_span = fn_sig
|
let sugg_span = fn_sig
|
||||||
.span
|
.span
|
||||||
.with_lo(fn_sig.span.lo() + BytePos::from_usize(fn_attrs.len()))
|
.with_lo(fn_sig.span.lo() + BytePos::from_usize(fn_attrs.len()))
|
||||||
.shrink_to_lo();
|
.shrink_to_lo();
|
||||||
|
let attr_snippet = snippet(cx, attr.span, "..");
|
||||||
|
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
NO_MANGLE_WITH_RUST_ABI,
|
NO_MANGLE_WITH_RUST_ABI,
|
||||||
fn_sig.span,
|
fn_sig.span,
|
||||||
"`#[no_mangle]` set on a function with the default (`Rust`) ABI",
|
format!("`{attr_snippet}` set on a function with the default (`Rust`) ABI"),
|
||||||
|diag| {
|
|diag| {
|
||||||
diag.span_suggestion(sugg_span, "set an ABI", "extern \"C\" ", app)
|
diag.span_suggestion(sugg_span, "set an ABI", "extern \"C\" ", app)
|
||||||
.span_suggestion(sugg_span, "or explicitly set the default", "extern \"Rust\" ", app);
|
.span_suggestion(sugg_span, "or explicitly set the default", "extern \"Rust\" ", app);
|
||||||
|
@ -2,30 +2,30 @@
|
|||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
#![warn(clippy::no_mangle_with_rust_abi)]
|
#![warn(clippy::no_mangle_with_rust_abi)]
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
|
fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
|
||||||
//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
//~^ ERROR: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
|
||||||
//~| NOTE: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings`
|
//~| NOTE: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings`
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
|
pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
|
||||||
//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
//~^ ERROR: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
|
||||||
|
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// This function shouldn't be called unless the horsemen are ready
|
/// This function shouldn't be called unless the horsemen are ready
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
|
pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
|
||||||
//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
//~^ ERROR: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
|
||||||
|
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// This function shouldn't be called unless the horsemen are ready
|
/// This function shouldn't be called unless the horsemen are ready
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
|
unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
|
||||||
//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
//~^ ERROR: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
|
fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
|
||||||
//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
//~^ ERROR: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
|
||||||
arg_one: u32,
|
arg_one: u32,
|
||||||
arg_two: usize,
|
arg_two: usize,
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
@ -33,13 +33,13 @@ fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Must not run on functions that explicitly opt in to using the Rust ABI with `extern "Rust"`
|
// Must not run on functions that explicitly opt in to using the Rust ABI with `extern "Rust"`
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
extern "Rust" fn rust_abi_fn_explicit_opt_in(arg_one: u32, arg_two: usize) {}
|
extern "Rust" fn rust_abi_fn_explicit_opt_in(arg_one: u32, arg_two: usize) {}
|
||||||
|
|
||||||
fn rust_abi_fn_again(arg_one: u32, arg_two: usize) {}
|
fn rust_abi_fn_again(arg_one: u32, arg_two: usize) {}
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
extern "C" fn c_abi_fn(arg_one: u32, arg_two: usize) {}
|
extern "C" fn c_abi_fn(arg_one: u32, arg_two: usize) {}
|
||||||
|
|
||||||
extern "C" fn c_abi_fn_again(arg_one: u32, arg_two: usize) {}
|
extern "C" fn c_abi_fn_again(arg_one: u32, arg_two: usize) {}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
|
||||||
--> tests/ui/no_mangle_with_rust_abi.rs:6:1
|
--> tests/ui/no_mangle_with_rust_abi.rs:6:1
|
||||||
|
|
|
|
||||||
LL | fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
|
LL | fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
|
||||||
@ -15,7 +15,7 @@ help: or explicitly set the default
|
|||||||
LL | extern "Rust" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
|
LL | extern "Rust" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
|
||||||
| +++++++++++++
|
| +++++++++++++
|
||||||
|
|
||||||
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
|
||||||
--> tests/ui/no_mangle_with_rust_abi.rs:11:1
|
--> tests/ui/no_mangle_with_rust_abi.rs:11:1
|
||||||
|
|
|
|
||||||
LL | pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
|
LL | pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
|
||||||
@ -30,7 +30,7 @@ help: or explicitly set the default
|
|||||||
LL | pub extern "Rust" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
|
LL | pub extern "Rust" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
|
||||||
| +++++++++++++
|
| +++++++++++++
|
||||||
|
|
||||||
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
|
||||||
--> tests/ui/no_mangle_with_rust_abi.rs:17:1
|
--> tests/ui/no_mangle_with_rust_abi.rs:17:1
|
||||||
|
|
|
|
||||||
LL | pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
|
LL | pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
|
||||||
@ -45,7 +45,7 @@ help: or explicitly set the default
|
|||||||
LL | pub unsafe extern "Rust" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
|
LL | pub unsafe extern "Rust" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
|
||||||
| +++++++++++++
|
| +++++++++++++
|
||||||
|
|
||||||
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
|
||||||
--> tests/ui/no_mangle_with_rust_abi.rs:23:1
|
--> tests/ui/no_mangle_with_rust_abi.rs:23:1
|
||||||
|
|
|
|
||||||
LL | unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
|
LL | unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
|
||||||
@ -60,7 +60,7 @@ help: or explicitly set the default
|
|||||||
LL | unsafe extern "Rust" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
|
LL | unsafe extern "Rust" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
|
||||||
| +++++++++++++
|
| +++++++++++++
|
||||||
|
|
||||||
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
|
||||||
--> tests/ui/no_mangle_with_rust_abi.rs:27:1
|
--> tests/ui/no_mangle_with_rust_abi.rs:27:1
|
||||||
|
|
|
|
||||||
LL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
|
LL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
|
||||||
|
57
tests/ui/no_mangle_with_rust_abi_2021.rs
Normal file
57
tests/ui/no_mangle_with_rust_abi_2021.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
//@edition:2021
|
||||||
|
//
|
||||||
|
// Edition 2024 requires the use of #[unsafe(no_mangle)]
|
||||||
|
|
||||||
|
//@no-rustfix: overlapping suggestions
|
||||||
|
#![allow(unused)]
|
||||||
|
#![warn(clippy::no_mangle_with_rust_abi)]
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
|
||||||
|
//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
||||||
|
//~| NOTE: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings`
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
|
||||||
|
//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
||||||
|
|
||||||
|
/// # Safety
|
||||||
|
/// This function shouldn't be called unless the horsemen are ready
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
|
||||||
|
//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
||||||
|
|
||||||
|
/// # Safety
|
||||||
|
/// This function shouldn't be called unless the horsemen are ready
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
|
||||||
|
//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
|
||||||
|
//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
||||||
|
arg_one: u32,
|
||||||
|
arg_two: usize,
|
||||||
|
) -> u32 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must not run on functions that explicitly opt in to using the Rust ABI with `extern "Rust"`
|
||||||
|
#[no_mangle]
|
||||||
|
#[rustfmt::skip]
|
||||||
|
extern "Rust" fn rust_abi_fn_explicit_opt_in(arg_one: u32, arg_two: usize) {}
|
||||||
|
|
||||||
|
fn rust_abi_fn_again(arg_one: u32, arg_two: usize) {}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
extern "C" fn c_abi_fn(arg_one: u32, arg_two: usize) {}
|
||||||
|
|
||||||
|
extern "C" fn c_abi_fn_again(arg_one: u32, arg_two: usize) {}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn c_abi_in_block(arg_one: u32, arg_two: usize);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// test code goes here
|
||||||
|
}
|
83
tests/ui/no_mangle_with_rust_abi_2021.stderr
Normal file
83
tests/ui/no_mangle_with_rust_abi_2021.stderr
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
||||||
|
--> tests/ui/no_mangle_with_rust_abi_2021.rs:10:1
|
||||||
|
|
|
||||||
|
LL | fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings`
|
||||||
|
= help: to override `-D warnings` add `#[allow(clippy::no_mangle_with_rust_abi)]`
|
||||||
|
help: set an ABI
|
||||||
|
|
|
||||||
|
LL | extern "C" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
|
||||||
|
| ++++++++++
|
||||||
|
help: or explicitly set the default
|
||||||
|
|
|
||||||
|
LL | extern "Rust" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
|
||||||
|
| +++++++++++++
|
||||||
|
|
||||||
|
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
||||||
|
--> tests/ui/no_mangle_with_rust_abi_2021.rs:15:1
|
||||||
|
|
|
||||||
|
LL | pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: set an ABI
|
||||||
|
|
|
||||||
|
LL | pub extern "C" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
|
||||||
|
| ++++++++++
|
||||||
|
help: or explicitly set the default
|
||||||
|
|
|
||||||
|
LL | pub extern "Rust" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
|
||||||
|
| +++++++++++++
|
||||||
|
|
||||||
|
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
||||||
|
--> tests/ui/no_mangle_with_rust_abi_2021.rs:21:1
|
||||||
|
|
|
||||||
|
LL | pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: set an ABI
|
||||||
|
|
|
||||||
|
LL | pub unsafe extern "C" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
|
||||||
|
| ++++++++++
|
||||||
|
help: or explicitly set the default
|
||||||
|
|
|
||||||
|
LL | pub unsafe extern "Rust" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
|
||||||
|
| +++++++++++++
|
||||||
|
|
||||||
|
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
||||||
|
--> tests/ui/no_mangle_with_rust_abi_2021.rs:27:1
|
||||||
|
|
|
||||||
|
LL | unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: set an ABI
|
||||||
|
|
|
||||||
|
LL | unsafe extern "C" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
|
||||||
|
| ++++++++++
|
||||||
|
help: or explicitly set the default
|
||||||
|
|
|
||||||
|
LL | unsafe extern "Rust" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
|
||||||
|
| +++++++++++++
|
||||||
|
|
||||||
|
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
|
||||||
|
--> tests/ui/no_mangle_with_rust_abi_2021.rs:31:1
|
||||||
|
|
|
||||||
|
LL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
|
||||||
|
LL | |
|
||||||
|
LL | | arg_one: u32,
|
||||||
|
LL | | arg_two: usize,
|
||||||
|
LL | | ) -> u32 {
|
||||||
|
| |________^
|
||||||
|
|
|
||||||
|
help: set an ABI
|
||||||
|
|
|
||||||
|
LL | extern "C" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
|
||||||
|
| ++++++++++
|
||||||
|
help: or explicitly set the default
|
||||||
|
|
|
||||||
|
LL | extern "Rust" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
|
||||||
|
| +++++++++++++
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user