From e546ac421bcc096e2b7a9c3f31d72e0f5d690ee5 Mon Sep 17 00:00:00 2001 From: Catherine Flores Date: Sat, 29 Jul 2023 01:30:07 -0500 Subject: [PATCH 1/3] Check for statics with a non `#[repr(Rust)]` type --- clippy_lints/src/no_mangle_with_rust_abi.rs | 129 ++++++++++++------ tests/ui/auxiliary/no_mangle_with_rust_abi.rs | 1 + tests/ui/no_mangle_with_rust_abi.rs | 15 ++ tests/ui/no_mangle_with_rust_abi.stderr | 39 +++++- 4 files changed, 138 insertions(+), 46 deletions(-) create mode 100644 tests/ui/auxiliary/no_mangle_with_rust_abi.rs diff --git a/clippy_lints/src/no_mangle_with_rust_abi.rs b/clippy_lints/src/no_mangle_with_rust_abi.rs index 8fd9ae351a0d..eefada52a8c0 100644 --- a/clippy_lints/src/no_mangle_with_rust_abi.rs +++ b/clippy_lints/src/no_mangle_with_rust_abi.rs @@ -1,32 +1,41 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_opt; use rustc_errors::Applicability; -use rustc_hir::{Item, ItemKind}; +use rustc_hir::{FnSig, Item, ItemKind, Ty}; +use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::{BytePos, Pos}; +use rustc_span::{sym, BytePos, Pos}; use rustc_target::spec::abi::Abi; declare_clippy_lint! { /// ### What it does - /// Checks for Rust ABI functions with the `#[no_mangle]` attribute. + /// Checks for Rust ABI functions or statics with the `#[no_mangle]` attribute. /// /// ### Why is this bad? - /// The Rust ABI is not stable, but in many simple cases matches - /// enough with the C ABI that it is possible to forget to add - /// `extern "C"` to a function called from C. Changes to the - /// Rust ABI can break this at any point. + /// The Rust ABI is not stable, but in many simple cases matches enough with the C ABI + /// that it is possible to forget to add `extern "C"` to a function called from C. + /// Changes to the Rust ABI can break this at any point. /// /// ### Example /// ```rust - /// #[no_mangle] - /// fn example(arg_one: u32, arg_two: usize) {} - /// ``` + /// #[no_mangle] + /// fn example(arg_one: u32, arg_two: usize) {} /// + /// pub struct UsingMeInCIsUB(u32, u32); + /// #[no_mangle] + /// pub static ZERO: UsingMeInCIsUB = UsingMeInCIsUB(0, 0); + /// ``` /// Use instead: /// ```rust - /// #[no_mangle] - /// extern "C" fn example(arg_one: u32, arg_two: usize) {} + /// #[no_mangle] + /// extern "C" fn example(arg_one: u32, arg_two: usize) {} + /// + /// #[repr(C)] + /// pub struct UsingMeInCIsFine(u32, u32); + /// #[no_mangle] + /// pub static ZERO: UsingMeInCIsFine = UsingMeInCIsFine(0, 0); /// ``` #[clippy::version = "1.69.0"] pub NO_MANGLE_WITH_RUST_ABI, @@ -37,33 +46,75 @@ declare_lint_pass!(NoMangleWithRustAbi => [NO_MANGLE_WITH_RUST_ABI]); impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { - if let ItemKind::Fn(fn_sig, _, _) = &item.kind { - let attrs = cx.tcx.hir().attrs(item.hir_id()); - let mut app = Applicability::MaybeIncorrect; - let snippet = snippet_with_applicability(cx, fn_sig.span, "..", &mut app); - for attr in attrs { - if let Some(ident) = attr.ident() - && ident.name == rustc_span::sym::no_mangle - && fn_sig.header.abi == Abi::Rust - && let Some((fn_attrs, _)) = snippet.split_once("fn") - && !fn_attrs.contains("extern") - { - let sugg_span = fn_sig.span - .with_lo(fn_sig.span.lo() + BytePos::from_usize(fn_attrs.len())) - .shrink_to_lo(); + if cx.tcx.get_attr(item.owner_id, sym::no_mangle).is_none() { + return; + } - span_lint_and_then( - cx, - NO_MANGLE_WITH_RUST_ABI, - fn_sig.span, - "`#[no_mangle]` set on a function with the default (`Rust`) ABI", - |diag| { - diag.span_suggestion(sugg_span, "set an ABI", "extern \"C\" ", app) - .span_suggestion(sugg_span, "or explicitly set the default", "extern \"Rust\" ", app); - }, - ); - } - } + match item.kind { + ItemKind::Fn(fn_sig, _, _) => check_fn(cx, fn_sig), + ItemKind::Static(ty, _, _) => check_static(cx, item, ty), + _ => {}, } } } + +/// Check for functions that are implicitly using the Rust ABI. +fn check_fn(cx: &LateContext<'_>, fn_sig: FnSig<'_>) { + if fn_sig.header.abi == Abi::Rust + && let Some(snippet) = snippet_opt(cx, fn_sig.span) + && let Some((fn_attrs, _)) = snippet.split_once("fn") + && !fn_attrs.contains("extern") + { + let sugg_span = fn_sig.span + .with_lo(fn_sig.span.lo() + BytePos::from_usize(fn_attrs.len())) + .shrink_to_lo(); + + span_lint_and_then( + cx, + NO_MANGLE_WITH_RUST_ABI, + fn_sig.span, + "`#[no_mangle]` set on a function with the default (`Rust`) ABI", + |diag| { + diag.span_suggestion( + sugg_span, + "set an ABI", + "extern \"C\" ", + Applicability::MaybeIncorrect, + ) + .span_suggestion( + sugg_span, + "or explicitly set the default", + "extern \"Rust\" ", + Applicability::MaybeIncorrect, + ); + }, + ); + } +} + +/// Check for static items with a type that is implicitly using the Rust ABI. +fn check_static(cx: &LateContext<'_>, item: &Item<'_>, ty: &Ty<'_>) { + // TODO(Centri3): Once/if Rust allows an explicit `#[repr(Rust)]`, change this to check for + // that. It should work by checking `ReprOptions::flags` for `IS_EXPLICIT_RUST`, whatever + // value that may be. + + if let ty::Adt(def, _) = hir_ty_to_ty(cx.tcx, ty).kind() + // No explicit representation. `align` and `pack` don't need to be checked as, + // afaik, what mostly matters is just the Rust ABI. + && def.repr().flags.bits() == 0 + { + span_lint_and_then( + cx, + NO_MANGLE_WITH_RUST_ABI, + item.span, + "`#[no_mangle]` set on a static with the default (`Rust`) ABI", + |diag| { + diag.span_note(ty.span, "this type is implicitly `#[repr(Rust)]`"); + + if def.did().is_local() { + diag.help("set an explicit ABI (like `#[repr(C)]`) on the type's definition"); + } + }, + ); + } +} diff --git a/tests/ui/auxiliary/no_mangle_with_rust_abi.rs b/tests/ui/auxiliary/no_mangle_with_rust_abi.rs new file mode 100644 index 000000000000..ede0f2e2d268 --- /dev/null +++ b/tests/ui/auxiliary/no_mangle_with_rust_abi.rs @@ -0,0 +1 @@ +pub struct UsingMeInCIsUB(pub u32, pub u32); diff --git a/tests/ui/no_mangle_with_rust_abi.rs b/tests/ui/no_mangle_with_rust_abi.rs index 818119f7be57..21c1a6ddbeb2 100644 --- a/tests/ui/no_mangle_with_rust_abi.rs +++ b/tests/ui/no_mangle_with_rust_abi.rs @@ -1,6 +1,21 @@ +//@aux-build:no_mangle_with_rust_abi.rs #![allow(unused)] #![warn(clippy::no_mangle_with_rust_abi)] +extern crate no_mangle_with_rust_abi as external; + +pub struct UsingMeInCIsUB(u32, u32); +#[no_mangle] +pub static ZERO_UB: UsingMeInCIsUB = UsingMeInCIsUB(0, 0); + +#[repr(C)] +pub struct UsingMeInCIsFine(u32, u32); +#[no_mangle] +pub static ZERO_DB: UsingMeInCIsFine = UsingMeInCIsFine(0, 0); + +#[no_mangle] +pub static ZERO_UB_AGAIN: external::UsingMeInCIsUB = external::UsingMeInCIsUB(0, 0); + #[no_mangle] fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} diff --git a/tests/ui/no_mangle_with_rust_abi.stderr b/tests/ui/no_mangle_with_rust_abi.stderr index da5d31d8f2d4..e428a21131a8 100644 --- a/tests/ui/no_mangle_with_rust_abi.stderr +++ b/tests/ui/no_mangle_with_rust_abi.stderr @@ -1,10 +1,35 @@ +error: `#[no_mangle]` set on a static with the default (`Rust`) ABI + --> $DIR/no_mangle_with_rust_abi.rs:9:1 + | +LL | pub static ZERO_UB: UsingMeInCIsUB = UsingMeInCIsUB(0, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this type is implicitly `#[repr(Rust)]` + --> $DIR/no_mangle_with_rust_abi.rs:9:21 + | +LL | pub static ZERO_UB: UsingMeInCIsUB = UsingMeInCIsUB(0, 0); + | ^^^^^^^^^^^^^^ + = help: set an explicit ABI (like `#[repr(C)]`) on the type's definition + = note: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings` + +error: `#[no_mangle]` set on a static with the default (`Rust`) ABI + --> $DIR/no_mangle_with_rust_abi.rs:17:1 + | +LL | pub static ZERO_UB_AGAIN: external::UsingMeInCIsUB = external::UsingMeInCIsUB(0, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this type is implicitly `#[repr(Rust)]` + --> $DIR/no_mangle_with_rust_abi.rs:17:27 + | +LL | pub static ZERO_UB_AGAIN: external::UsingMeInCIsUB = external::UsingMeInCIsUB(0, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + error: `#[no_mangle]` set on a function with the default (`Rust`) ABI - --> $DIR/no_mangle_with_rust_abi.rs:5:1 + --> $DIR/no_mangle_with_rust_abi.rs:20: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: set an ABI | LL | extern "C" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} @@ -15,7 +40,7 @@ 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 - --> $DIR/no_mangle_with_rust_abi.rs:8:1 + --> $DIR/no_mangle_with_rust_abi.rs:23:1 | LL | pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -30,7 +55,7 @@ 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 - --> $DIR/no_mangle_with_rust_abi.rs:13:1 + --> $DIR/no_mangle_with_rust_abi.rs:28:1 | LL | pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,7 +70,7 @@ 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 - --> $DIR/no_mangle_with_rust_abi.rs:18:1 + --> $DIR/no_mangle_with_rust_abi.rs:33:1 | LL | unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +85,7 @@ 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 - --> $DIR/no_mangle_with_rust_abi.rs:21:1 + --> $DIR/no_mangle_with_rust_abi.rs:36:1 | LL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( LL | | arg_one: u32, @@ -77,5 +102,5 @@ 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 +error: aborting due to 7 previous errors From 168b0a0dbeaa6f26bd2e6db88ab855ec8e0befae Mon Sep 17 00:00:00 2001 From: Catherine Flores Date: Tue, 1 Aug 2023 01:35:13 -0500 Subject: [PATCH 2/3] Add UB note and lint on randomized layout --- clippy_lints/src/no_mangle_with_rust_abi.rs | 37 +++++++++++---------- tests/ui/no_mangle_with_rust_abi.stderr | 2 ++ 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/clippy_lints/src/no_mangle_with_rust_abi.rs b/clippy_lints/src/no_mangle_with_rust_abi.rs index eefada52a8c0..3f517569fd5f 100644 --- a/clippy_lints/src/no_mangle_with_rust_abi.rs +++ b/clippy_lints/src/no_mangle_with_rust_abi.rs @@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet_opt; use rustc_errors::Applicability; use rustc_hir::{FnSig, Item, ItemKind, Ty}; -use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -65,7 +64,8 @@ fn check_fn(cx: &LateContext<'_>, fn_sig: FnSig<'_>) { && let Some((fn_attrs, _)) = snippet.split_once("fn") && !fn_attrs.contains("extern") { - let sugg_span = fn_sig.span + let sugg_span = fn_sig + .span .with_lo(fn_sig.span.lo() + BytePos::from_usize(fn_attrs.len())) .shrink_to_lo(); @@ -75,12 +75,11 @@ fn check_fn(cx: &LateContext<'_>, fn_sig: FnSig<'_>) { fn_sig.span, "`#[no_mangle]` set on a function with the default (`Rust`) ABI", |diag| { - diag.span_suggestion( - sugg_span, - "set an ABI", - "extern \"C\" ", - Applicability::MaybeIncorrect, + diag.note_once( + "calling this function in an external content is Undefined Behavior, as its calling convention \ + (ABI) is undefined", ) + .span_suggestion(sugg_span, "set an ABI", "extern \"C\" ", Applicability::MaybeIncorrect) .span_suggestion( sugg_span, "or explicitly set the default", @@ -94,24 +93,28 @@ fn check_fn(cx: &LateContext<'_>, fn_sig: FnSig<'_>) { /// Check for static items with a type that is implicitly using the Rust ABI. fn check_static(cx: &LateContext<'_>, item: &Item<'_>, ty: &Ty<'_>) { - // TODO(Centri3): Once/if Rust allows an explicit `#[repr(Rust)]`, change this to check for - // that. It should work by checking `ReprOptions::flags` for `IS_EXPLICIT_RUST`, whatever - // value that may be. + // TODO(Centri3): Add a check here for `#[repr(Rust)]` once #114201 is merged. - if let ty::Adt(def, _) = hir_ty_to_ty(cx.tcx, ty).kind() - // No explicit representation. `align` and `pack` don't need to be checked as, - // afaik, what mostly matters is just the Rust ABI. - && def.repr().flags.bits() == 0 - { + if let Some(is_local) = match cx.tcx.type_of(item.owner_id).skip_binder().kind() { + ty::Adt(def, _) => { + let repr = def.repr(); + (!repr.c() && !repr.transparent() && !repr.simd() && repr.int.is_none()).then(|| def.did().is_local()) + }, + ty::Tuple(tys) => (tys.len() != 0).then_some(false), + _ => return, + } { span_lint_and_then( cx, NO_MANGLE_WITH_RUST_ABI, item.span, "`#[no_mangle]` set on a static with the default (`Rust`) ABI", |diag| { - diag.span_note(ty.span, "this type is implicitly `#[repr(Rust)]`"); + diag.span_note(ty.span, "this type is implicitly `#[repr(Rust)]`") + .note_once( + "usage of this static in an external context is Undefined Behavior, as its layout is undefined", + ); - if def.did().is_local() { + if is_local { diag.help("set an explicit ABI (like `#[repr(C)]`) on the type's definition"); } }, diff --git a/tests/ui/no_mangle_with_rust_abi.stderr b/tests/ui/no_mangle_with_rust_abi.stderr index e428a21131a8..993db5550292 100644 --- a/tests/ui/no_mangle_with_rust_abi.stderr +++ b/tests/ui/no_mangle_with_rust_abi.stderr @@ -9,6 +9,7 @@ note: this type is implicitly `#[repr(Rust)]` | LL | pub static ZERO_UB: UsingMeInCIsUB = UsingMeInCIsUB(0, 0); | ^^^^^^^^^^^^^^ + = note: usage of this static in an external context is Undefined Behavior, as its layout is undefined = help: set an explicit ABI (like `#[repr(C)]`) on the type's definition = note: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings` @@ -30,6 +31,7 @@ error: `#[no_mangle]` set on a function with the default (`Rust`) ABI LL | fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: calling this function in an external content is Undefined Behavior, as its calling convention (ABI) is undefined help: set an ABI | LL | extern "C" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} From fbee96925e76d22b405a824678b79845248f8835 Mon Sep 17 00:00:00 2001 From: Catherine Flores Date: Sat, 5 Aug 2023 08:44:08 -0500 Subject: [PATCH 3/3] Refine message for note --- clippy_lints/src/no_mangle_with_rust_abi.rs | 7 ++-- tests/ui/no_mangle_with_rust_abi.rs | 24 +++++++++++++ tests/ui/no_mangle_with_rust_abi.stderr | 37 ++++++++++++++------- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/clippy_lints/src/no_mangle_with_rust_abi.rs b/clippy_lints/src/no_mangle_with_rust_abi.rs index 3f517569fd5f..60fd758a5502 100644 --- a/clippy_lints/src/no_mangle_with_rust_abi.rs +++ b/clippy_lints/src/no_mangle_with_rust_abi.rs @@ -76,8 +76,8 @@ fn check_fn(cx: &LateContext<'_>, fn_sig: FnSig<'_>) { "`#[no_mangle]` set on a function with the default (`Rust`) ABI", |diag| { diag.note_once( - "calling this function in an external content is Undefined Behavior, as its calling convention \ - (ABI) is undefined", + "this function's calling convention (ABI) is unstable, and changes to the `Rust` ABI can break \ + this at any time", ) .span_suggestion(sugg_span, "set an ABI", "extern \"C\" ", Applicability::MaybeIncorrect) .span_suggestion( @@ -111,7 +111,8 @@ fn check_static(cx: &LateContext<'_>, item: &Item<'_>, ty: &Ty<'_>) { |diag| { diag.span_note(ty.span, "this type is implicitly `#[repr(Rust)]`") .note_once( - "usage of this static in an external context is Undefined Behavior, as its layout is undefined", + "this static's layout (ABI) is unstable, and changes to the `Rust` ABI can break this at any \ + time", ); if is_local { diff --git a/tests/ui/no_mangle_with_rust_abi.rs b/tests/ui/no_mangle_with_rust_abi.rs index 21c1a6ddbeb2..068cee4027de 100644 --- a/tests/ui/no_mangle_with_rust_abi.rs +++ b/tests/ui/no_mangle_with_rust_abi.rs @@ -4,6 +4,8 @@ extern crate no_mangle_with_rust_abi as external; +use std::ptr::null; + pub struct UsingMeInCIsUB(u32, u32); #[no_mangle] pub static ZERO_UB: UsingMeInCIsUB = UsingMeInCIsUB(0, 0); @@ -16,6 +18,28 @@ pub static ZERO_DB: UsingMeInCIsFine = UsingMeInCIsFine(0, 0); #[no_mangle] pub static ZERO_UB_AGAIN: external::UsingMeInCIsUB = external::UsingMeInCIsUB(0, 0); +#[no_mangle] +pub static U32_DB: u32 = 0; + +#[repr(transparent)] +pub struct PtrTransparent(*const u32); + +unsafe impl Send for PtrTransparent {} + +unsafe impl Sync for PtrTransparent {} + +pub struct Ptr(*const u32); + +unsafe impl Send for Ptr {} + +unsafe impl Sync for Ptr {} + +#[no_mangle] +pub static PTR_DB: PtrTransparent = PtrTransparent(null()); + +#[no_mangle] +pub static PTR_UB: Ptr = Ptr(null()); + #[no_mangle] fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} diff --git a/tests/ui/no_mangle_with_rust_abi.stderr b/tests/ui/no_mangle_with_rust_abi.stderr index 993db5550292..6ecbffdf0055 100644 --- a/tests/ui/no_mangle_with_rust_abi.stderr +++ b/tests/ui/no_mangle_with_rust_abi.stderr @@ -1,37 +1,50 @@ error: `#[no_mangle]` set on a static with the default (`Rust`) ABI - --> $DIR/no_mangle_with_rust_abi.rs:9:1 + --> $DIR/no_mangle_with_rust_abi.rs:11:1 | LL | pub static ZERO_UB: UsingMeInCIsUB = UsingMeInCIsUB(0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this type is implicitly `#[repr(Rust)]` - --> $DIR/no_mangle_with_rust_abi.rs:9:21 + --> $DIR/no_mangle_with_rust_abi.rs:11:21 | LL | pub static ZERO_UB: UsingMeInCIsUB = UsingMeInCIsUB(0, 0); | ^^^^^^^^^^^^^^ - = note: usage of this static in an external context is Undefined Behavior, as its layout is undefined + = note: this static's layout (ABI) is unstable, and changes to the `Rust` ABI can break this at any time = help: set an explicit ABI (like `#[repr(C)]`) on the type's definition = note: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings` error: `#[no_mangle]` set on a static with the default (`Rust`) ABI - --> $DIR/no_mangle_with_rust_abi.rs:17:1 + --> $DIR/no_mangle_with_rust_abi.rs:19:1 | LL | pub static ZERO_UB_AGAIN: external::UsingMeInCIsUB = external::UsingMeInCIsUB(0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this type is implicitly `#[repr(Rust)]` - --> $DIR/no_mangle_with_rust_abi.rs:17:27 + --> $DIR/no_mangle_with_rust_abi.rs:19:27 | LL | pub static ZERO_UB_AGAIN: external::UsingMeInCIsUB = external::UsingMeInCIsUB(0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^ +error: `#[no_mangle]` set on a static with the default (`Rust`) ABI + --> $DIR/no_mangle_with_rust_abi.rs:41:1 + | +LL | pub static PTR_UB: Ptr = Ptr(null()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this type is implicitly `#[repr(Rust)]` + --> $DIR/no_mangle_with_rust_abi.rs:41:20 + | +LL | pub static PTR_UB: Ptr = Ptr(null()); + | ^^^ + = help: set an explicit ABI (like `#[repr(C)]`) on the type's definition + error: `#[no_mangle]` set on a function with the default (`Rust`) ABI - --> $DIR/no_mangle_with_rust_abi.rs:20:1 + --> $DIR/no_mangle_with_rust_abi.rs:44:1 | LL | fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: calling this function in an external content is Undefined Behavior, as its calling convention (ABI) is undefined + = note: this function's calling convention (ABI) is unstable, and changes to the `Rust` ABI can break this at any time help: set an ABI | LL | extern "C" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} @@ -42,7 +55,7 @@ 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 - --> $DIR/no_mangle_with_rust_abi.rs:23:1 + --> $DIR/no_mangle_with_rust_abi.rs:47:1 | LL | pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +70,7 @@ 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 - --> $DIR/no_mangle_with_rust_abi.rs:28:1 + --> $DIR/no_mangle_with_rust_abi.rs:52:1 | LL | pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +85,7 @@ 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 - --> $DIR/no_mangle_with_rust_abi.rs:33:1 + --> $DIR/no_mangle_with_rust_abi.rs:57:1 | LL | unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -87,7 +100,7 @@ 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 - --> $DIR/no_mangle_with_rust_abi.rs:36:1 + --> $DIR/no_mangle_with_rust_abi.rs:60:1 | LL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( LL | | arg_one: u32, @@ -104,5 +117,5 @@ 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 7 previous errors +error: aborting due to 8 previous errors