From 24de5ec5c63b8d2f6f61f79a2783afdf1c84a49a Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 13 Sep 2025 14:02:04 +0200 Subject: [PATCH 1/3] Add lint warn about clashing function names with fundamental functions --- Cargo.lock | 1 + compiler/rustc_lint/Cargo.toml | 1 + compiler/rustc_lint/messages.ftl | 5 + .../rustc_lint/src/fundamental_functions.rs | 71 ++++++++++++ compiler/rustc_lint/src/lib.rs | 3 + compiler/rustc_lint/src/lints.rs | 10 ++ compiler/rustc_symbol_mangling/src/lib.rs | 47 +++++--- ...ing-fn-names-with-fundamental-functions.rs | 59 ++++++++++ ...fn-names-with-fundamental-functions.stderr | 107 ++++++++++++++++++ 9 files changed, 287 insertions(+), 17 deletions(-) create mode 100644 compiler/rustc_lint/src/fundamental_functions.rs create mode 100644 tests/ui/lint/clashing-fn-names-with-fundamental-functions.rs create mode 100644 tests/ui/lint/clashing-fn-names-with-fundamental-functions.stderr diff --git a/Cargo.lock b/Cargo.lock index 2dc6e8ff10320..e527318166308 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4042,6 +4042,7 @@ dependencies = [ "rustc_parse_format", "rustc_session", "rustc_span", + "rustc_symbol_mangling", "rustc_target", "rustc_trait_selection", "smallvec", diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml index 3a50aac50cb3e..7c86d2eea9620 100644 --- a/compiler/rustc_lint/Cargo.toml +++ b/compiler/rustc_lint/Cargo.toml @@ -22,6 +22,7 @@ rustc_middle = { path = "../rustc_middle" } rustc_parse_format = { path = "../rustc_parse_format" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } +rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 417e5a97069c3..66594fb7ce0c5 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -195,6 +195,11 @@ lint_cfg_attr_no_attributes = lint_check_name_unknown_tool = unknown lint tool: `{$tool_name}` +lint_clashing_function_names_with_fundamental_functions = this function symbol name `{$symbol_name}` clashes with the fundamental functions expected with `core` and `std` + .match_exactly = extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) + .learn_more = see for the more details + .help = either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "{$symbol_name}")]` if present + lint_closure_returning_async_block = closure returning async block can be made into an async closure .label = this async block can be removed, and the closure can be turned into an async closure .suggestion = turn this into an async closure diff --git a/compiler/rustc_lint/src/fundamental_functions.rs b/compiler/rustc_lint/src/fundamental_functions.rs new file mode 100644 index 0000000000000..bbb55436ccde9 --- /dev/null +++ b/compiler/rustc_lint/src/fundamental_functions.rs @@ -0,0 +1,71 @@ +use rustc_hir as hir; +use rustc_session::{declare_lint, declare_lint_pass}; + +use crate::lints::ClashingFunctionNamesWithFundamentalFunctions; +use crate::{LateContext, LateLintPass, LintContext}; + +declare_lint! { + /// The `clashing_function_names_with_fundamental_functions` lint checks for function + /// name whose name clash with a fundamental functions expected by `core` and `std`. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// #![deny(clashing_function_names_with_fundamental_functions)] + /// + /// #[unsafe(no_mangle)] + /// pub fn strlen() {} // clash with the libc `strlen` function + /// // care must be taken when implementing this function + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Up-most care is required when overriding those fundamental functions assumed and + /// used by the standard library. They must follow the C specification, not use any + /// standard-library facility or undefined behavior may occur. + /// + /// The symbols currently checked are respectively: + /// - from `core`[^1]: `memcpy`, `memmove`, `memset`, `memcmp`, `bcmp`, `strlen` + /// - from `std`: `read`, `write`, `open`, `close` + /// + /// [^1]: https://doc.rust-lang.org/core/index.html#how-to-use-the-core-library + pub CLASHING_FUNCTION_NAMES_WITH_FUNDAMENTAL_FUNCTIONS, + Warn, + "using a function name that clashes with fundamental function names" +} + +declare_lint_pass!(FundamentalFunctions => [CLASHING_FUNCTION_NAMES_WITH_FUNDAMENTAL_FUNCTIONS]); + +static CORE_FUNDAMENTAL_FUNCTION_NAMES: &[&str] = + &["memcpy", "memmove", "memset", "memcmp", "bcmp", "strlen"]; + +static STD_FUNDAMENTAL_FUNCTION_NAMES: &[&str] = &["open", "read", "write", "close"]; + +impl<'tcx> LateLintPass<'tcx> for FundamentalFunctions { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { + let hir::ItemKind::Fn { sig: _, ident: _, generics: _, body: _, has_body: true } = + item.kind + else { + return; + }; + + let Some(symbol_name) = rustc_symbol_mangling::symbol_name_without_mangling( + cx.tcx, + rustc_middle::ty::InstanceKind::Item(item.owner_id.to_def_id()), + ) else { + return; + }; + + if CORE_FUNDAMENTAL_FUNCTION_NAMES.contains(&&*symbol_name) + || STD_FUNDAMENTAL_FUNCTION_NAMES.contains(&&*symbol_name) + { + cx.emit_span_lint( + CLASHING_FUNCTION_NAMES_WITH_FUNDAMENTAL_FUNCTIONS, + item.span, + ClashingFunctionNamesWithFundamentalFunctions { symbol_name }, + ); + } + } +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 9bb53fea54a18..0d0450844a038 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -48,6 +48,7 @@ mod errors; mod expect; mod for_loops_over_fallibles; mod foreign_modules; +mod fundamental_functions; mod if_let_rescope; mod impl_trait_overcaptures; mod internal; @@ -92,6 +93,7 @@ use deref_into_dyn_supertrait::*; use drop_forget_useless::*; use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums; use for_loops_over_fallibles::*; +use fundamental_functions::*; use if_let_rescope::IfLetRescope; use impl_trait_overcaptures::ImplTraitOvercaptures; use internal::*; @@ -240,6 +242,7 @@ late_lint_methods!( AsyncClosureUsage: AsyncClosureUsage, AsyncFnInTrait: AsyncFnInTrait, NonLocalDefinitions: NonLocalDefinitions::default(), + FundamentalFunctions: FundamentalFunctions, ImplTraitOvercaptures: ImplTraitOvercaptures, IfLetRescope: IfLetRescope::default(), StaticMutRefs: StaticMutRefs, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 56d65ed08f9e3..2a9405a1233d2 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -705,6 +705,16 @@ pub(crate) enum UseLetUnderscoreIgnoreSuggestion { }, } +// fundamental_functions.rs +#[derive(LintDiagnostic)] +#[diag(lint_clashing_function_names_with_fundamental_functions)] +#[note(lint_match_exactly)] +#[note(lint_learn_more)] +#[help] +pub(crate) struct ClashingFunctionNamesWithFundamentalFunctions { + pub symbol_name: String, +} + // drop_forget_useless.rs #[derive(LintDiagnostic)] #[diag(lint_dropping_references)] diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index d97ee95652530..a3092177c5c17 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -100,7 +100,7 @@ use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; use rustc_middle::query::Providers; -use rustc_middle::ty::{self, Instance, TyCtxt}; +use rustc_middle::ty::{self, Instance, InstanceKind, TyCtxt}; use rustc_session::config::SymbolManglingVersion; use tracing::debug; @@ -158,29 +158,22 @@ pub fn typeid_for_trait_ref<'tcx>( v0::mangle_typeid_for_trait_ref(tcx, trait_ref) } -/// Computes the symbol name for the given instance. This function will call -/// `compute_instantiating_crate` if it needs to factor the instantiating crate -/// into the symbol name. -fn compute_symbol_name<'tcx>( +pub fn symbol_name_without_mangling<'tcx>( tcx: TyCtxt<'tcx>, - instance: Instance<'tcx>, - compute_instantiating_crate: impl FnOnce() -> CrateNum, -) -> String { - let def_id = instance.def_id(); - let args = instance.args; - - debug!("symbol_name(def_id={:?}, args={:?})", def_id, args); + instance_kind: InstanceKind<'tcx>, +) -> Option { + let def_id = instance_kind.def_id(); if let Some(def_id) = def_id.as_local() { if tcx.proc_macro_decls_static(()) == Some(def_id) { let stable_crate_id = tcx.stable_crate_id(LOCAL_CRATE); - return tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id); + return Some(tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id)); } } // FIXME(eddyb) Precompute a custom symbol name based on attributes. let attrs = if tcx.def_kind(def_id).has_codegen_attrs() { - &tcx.codegen_instance_attrs(instance.def) + &tcx.codegen_instance_attrs(instance_kind) } else { CodegenFnAttrs::EMPTY }; @@ -206,7 +199,7 @@ fn compute_symbol_name<'tcx>( // legacy symbol mangling scheme. let name = if let Some(name) = attrs.symbol_name { name } else { tcx.item_name(def_id) }; - return v0::mangle_internal_symbol(tcx, name.as_str()); + return Some(v0::mangle_internal_symbol(tcx, name.as_str())); } let wasm_import_module_exception_force_mangling = { @@ -234,15 +227,35 @@ fn compute_symbol_name<'tcx>( if !wasm_import_module_exception_force_mangling { if let Some(name) = attrs.symbol_name { // Use provided name - return name.to_string(); + return Some(name.to_string()); } if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { // Don't mangle - return tcx.item_name(def_id).to_string(); + return Some(tcx.item_name(def_id).to_string()); } } + None +} + +/// Computes the symbol name for the given instance. This function will call +/// `compute_instantiating_crate` if it needs to factor the instantiating crate +/// into the symbol name. +fn compute_symbol_name<'tcx>( + tcx: TyCtxt<'tcx>, + instance: Instance<'tcx>, + compute_instantiating_crate: impl FnOnce() -> CrateNum, +) -> String { + let def_id = instance.def_id(); + let args = instance.args; + + debug!("symbol_name(def_id={:?}, args={:?})", def_id, args); + + if let Some(symbol) = symbol_name_without_mangling(tcx, instance.def) { + return symbol; + } + // If we're dealing with an instance of a function that's inlined from // another crate but we're marking it as globally shared to our // compilation (aka we're not making an internal copy in each of our diff --git a/tests/ui/lint/clashing-fn-names-with-fundamental-functions.rs b/tests/ui/lint/clashing-fn-names-with-fundamental-functions.rs new file mode 100644 index 0000000000000..c52f432981188 --- /dev/null +++ b/tests/ui/lint/clashing-fn-names-with-fundamental-functions.rs @@ -0,0 +1,59 @@ +//@ check-pass +//@ edition: 2021 + +use std::ffi::c_void; + +// From core + +#[no_mangle] +pub extern "C" fn memcpy( + dest: *mut c_void, + src: *const c_void, + n: i64, +) -> *mut c_void { std::ptr::null_mut() } +//~^^^^^ WARN `memcpy` clashes + +#[no_mangle] +pub fn memmove() {} +//~^ WARN `memmove` clashes + +#[no_mangle] +pub fn memset() {} +//~^ WARN `memset` clashes + +#[no_mangle] +pub fn memcmp() {} +//~^ WARN `memcmp` clashes + +#[export_name = "bcmp"] +pub fn bcmp_() {} +//~^ WARN `bcmp` clashes + +#[no_mangle] +pub fn strlen() {} +//~^ WARN `strlen` clashes + +// From std + +#[no_mangle] +pub fn open() {} +//~^ WARN `open` clashes + +#[export_name = "read"] +pub async fn read1() {} +//~^ WARN `read` clashes + +#[export_name = "write"] +pub fn write1() {} +//~^ WARN `write` clashes + +#[export_name = "close"] +pub fn close_() {} +//~^ WARN `close` clashes + +extern "C" { + // No warning, not a body. + pub fn close(a: i32) -> i32; +} + +fn main() {} diff --git a/tests/ui/lint/clashing-fn-names-with-fundamental-functions.stderr b/tests/ui/lint/clashing-fn-names-with-fundamental-functions.stderr new file mode 100644 index 0000000000000..55fe4e5eb1e85 --- /dev/null +++ b/tests/ui/lint/clashing-fn-names-with-fundamental-functions.stderr @@ -0,0 +1,107 @@ +warning: this function symbol name `memcpy` clashes with the fundamental functions expected with `core` and `std` + --> $DIR/clashing-fn-names-with-fundamental-functions.rs:9:1 + | +LL | / pub extern "C" fn memcpy( +LL | | dest: *mut c_void, +LL | | src: *const c_void, +LL | | n: i64, +LL | | ) -> *mut c_void { std::ptr::null_mut() } + | |_________________________________________^ + | + = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "memcpy")]` if present + = note: `#[warn(clashing_function_names_with_fundamental_functions)]` on by default + +warning: this function symbol name `memmove` clashes with the fundamental functions expected with `core` and `std` + --> $DIR/clashing-fn-names-with-fundamental-functions.rs:17:1 + | +LL | pub fn memmove() {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "memmove")]` if present + +warning: this function symbol name `memset` clashes with the fundamental functions expected with `core` and `std` + --> $DIR/clashing-fn-names-with-fundamental-functions.rs:21:1 + | +LL | pub fn memset() {} + | ^^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "memset")]` if present + +warning: this function symbol name `memcmp` clashes with the fundamental functions expected with `core` and `std` + --> $DIR/clashing-fn-names-with-fundamental-functions.rs:25:1 + | +LL | pub fn memcmp() {} + | ^^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "memcmp")]` if present + +warning: this function symbol name `bcmp` clashes with the fundamental functions expected with `core` and `std` + --> $DIR/clashing-fn-names-with-fundamental-functions.rs:29:1 + | +LL | pub fn bcmp_() {} + | ^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "bcmp")]` if present + +warning: this function symbol name `strlen` clashes with the fundamental functions expected with `core` and `std` + --> $DIR/clashing-fn-names-with-fundamental-functions.rs:33:1 + | +LL | pub fn strlen() {} + | ^^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "strlen")]` if present + +warning: this function symbol name `open` clashes with the fundamental functions expected with `core` and `std` + --> $DIR/clashing-fn-names-with-fundamental-functions.rs:39:1 + | +LL | pub fn open() {} + | ^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "open")]` if present + +warning: this function symbol name `read` clashes with the fundamental functions expected with `core` and `std` + --> $DIR/clashing-fn-names-with-fundamental-functions.rs:43:1 + | +LL | pub async fn read1() {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "read")]` if present + +warning: this function symbol name `write` clashes with the fundamental functions expected with `core` and `std` + --> $DIR/clashing-fn-names-with-fundamental-functions.rs:47:1 + | +LL | pub fn write1() {} + | ^^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "write")]` if present + +warning: this function symbol name `close` clashes with the fundamental functions expected with `core` and `std` + --> $DIR/clashing-fn-names-with-fundamental-functions.rs:51:1 + | +LL | pub fn close_() {} + | ^^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "close")]` if present + +warning: 10 warnings emitted + From e0952b296a39cbf35459ed49d55527513b767241 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 13 Sep 2025 21:22:18 +0200 Subject: [PATCH 2/3] Rename lint to `redefining_runtime_symbols` --- compiler/rustc_lint/messages.ftl | 6 +- .../rustc_lint/src/fundamental_functions.rs | 71 ------------ compiler/rustc_lint/src/lib.rs | 6 +- compiler/rustc_lint/src/lints.rs | 6 +- .../src/redefining_runtime_symbols.rs | 72 ++++++++++++ ...fn-names-with-fundamental-functions.stderr | 107 ------------------ ...tions.rs => redefining-runtime-symbols.rs} | 22 ++-- .../ui/lint/redefining-runtime-symbols.stderr | 107 ++++++++++++++++++ 8 files changed, 199 insertions(+), 198 deletions(-) delete mode 100644 compiler/rustc_lint/src/fundamental_functions.rs create mode 100644 compiler/rustc_lint/src/redefining_runtime_symbols.rs delete mode 100644 tests/ui/lint/clashing-fn-names-with-fundamental-functions.stderr rename tests/ui/lint/{clashing-fn-names-with-fundamental-functions.rs => redefining-runtime-symbols.rs} (53%) create mode 100644 tests/ui/lint/redefining-runtime-symbols.stderr diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 66594fb7ce0c5..508df77639e3e 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -195,10 +195,10 @@ lint_cfg_attr_no_attributes = lint_check_name_unknown_tool = unknown lint tool: `{$tool_name}` -lint_clashing_function_names_with_fundamental_functions = this function symbol name `{$symbol_name}` clashes with the fundamental functions expected with `core` and `std` - .match_exactly = extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) +lint_redefining_runtime_symbols = redefinition of the runtime `{$symbol_name}` symbol used by the standard library + .match_exactly = extra care must be taken when redefining those symbols, they must match exactly (ABI, function arguments, function return type, behavior, ...) .learn_more = see for the more details - .help = either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "{$symbol_name}")]` if present + .help = either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "{$symbol_name}")]` lint_closure_returning_async_block = closure returning async block can be made into an async closure .label = this async block can be removed, and the closure can be turned into an async closure diff --git a/compiler/rustc_lint/src/fundamental_functions.rs b/compiler/rustc_lint/src/fundamental_functions.rs deleted file mode 100644 index bbb55436ccde9..0000000000000 --- a/compiler/rustc_lint/src/fundamental_functions.rs +++ /dev/null @@ -1,71 +0,0 @@ -use rustc_hir as hir; -use rustc_session::{declare_lint, declare_lint_pass}; - -use crate::lints::ClashingFunctionNamesWithFundamentalFunctions; -use crate::{LateContext, LateLintPass, LintContext}; - -declare_lint! { - /// The `clashing_function_names_with_fundamental_functions` lint checks for function - /// name whose name clash with a fundamental functions expected by `core` and `std`. - /// - /// ### Example - /// - /// ```rust,compile_fail - /// #![deny(clashing_function_names_with_fundamental_functions)] - /// - /// #[unsafe(no_mangle)] - /// pub fn strlen() {} // clash with the libc `strlen` function - /// // care must be taken when implementing this function - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// Up-most care is required when overriding those fundamental functions assumed and - /// used by the standard library. They must follow the C specification, not use any - /// standard-library facility or undefined behavior may occur. - /// - /// The symbols currently checked are respectively: - /// - from `core`[^1]: `memcpy`, `memmove`, `memset`, `memcmp`, `bcmp`, `strlen` - /// - from `std`: `read`, `write`, `open`, `close` - /// - /// [^1]: https://doc.rust-lang.org/core/index.html#how-to-use-the-core-library - pub CLASHING_FUNCTION_NAMES_WITH_FUNDAMENTAL_FUNCTIONS, - Warn, - "using a function name that clashes with fundamental function names" -} - -declare_lint_pass!(FundamentalFunctions => [CLASHING_FUNCTION_NAMES_WITH_FUNDAMENTAL_FUNCTIONS]); - -static CORE_FUNDAMENTAL_FUNCTION_NAMES: &[&str] = - &["memcpy", "memmove", "memset", "memcmp", "bcmp", "strlen"]; - -static STD_FUNDAMENTAL_FUNCTION_NAMES: &[&str] = &["open", "read", "write", "close"]; - -impl<'tcx> LateLintPass<'tcx> for FundamentalFunctions { - fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { - let hir::ItemKind::Fn { sig: _, ident: _, generics: _, body: _, has_body: true } = - item.kind - else { - return; - }; - - let Some(symbol_name) = rustc_symbol_mangling::symbol_name_without_mangling( - cx.tcx, - rustc_middle::ty::InstanceKind::Item(item.owner_id.to_def_id()), - ) else { - return; - }; - - if CORE_FUNDAMENTAL_FUNCTION_NAMES.contains(&&*symbol_name) - || STD_FUNDAMENTAL_FUNCTION_NAMES.contains(&&*symbol_name) - { - cx.emit_span_lint( - CLASHING_FUNCTION_NAMES_WITH_FUNDAMENTAL_FUNCTIONS, - item.span, - ClashingFunctionNamesWithFundamentalFunctions { symbol_name }, - ); - } - } -} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 0d0450844a038..e2a5fe0524e34 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -48,7 +48,6 @@ mod errors; mod expect; mod for_loops_over_fallibles; mod foreign_modules; -mod fundamental_functions; mod if_let_rescope; mod impl_trait_overcaptures; mod internal; @@ -71,6 +70,7 @@ mod pass_by_value; mod passes; mod precedence; mod ptr_nulls; +mod redefining_runtime_symbols; mod redundant_semicolon; mod reference_casting; mod shadowed_into_iter; @@ -93,7 +93,6 @@ use deref_into_dyn_supertrait::*; use drop_forget_useless::*; use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums; use for_loops_over_fallibles::*; -use fundamental_functions::*; use if_let_rescope::IfLetRescope; use impl_trait_overcaptures::ImplTraitOvercaptures; use internal::*; @@ -112,6 +111,7 @@ use opaque_hidden_inferred_bound::*; use pass_by_value::*; use precedence::*; use ptr_nulls::*; +use redefining_runtime_symbols::*; use redundant_semicolon::*; use reference_casting::*; use rustc_hir::def_id::LocalModDefId; @@ -242,7 +242,7 @@ late_lint_methods!( AsyncClosureUsage: AsyncClosureUsage, AsyncFnInTrait: AsyncFnInTrait, NonLocalDefinitions: NonLocalDefinitions::default(), - FundamentalFunctions: FundamentalFunctions, + RedefiningRuntimeSymbols: RedefiningRuntimeSymbols, ImplTraitOvercaptures: ImplTraitOvercaptures, IfLetRescope: IfLetRescope::default(), StaticMutRefs: StaticMutRefs, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 2a9405a1233d2..3889f2d2e3cce 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -705,13 +705,13 @@ pub(crate) enum UseLetUnderscoreIgnoreSuggestion { }, } -// fundamental_functions.rs +// redefining_runtime_symbols.rs #[derive(LintDiagnostic)] -#[diag(lint_clashing_function_names_with_fundamental_functions)] +#[diag(lint_redefining_runtime_symbols)] #[note(lint_match_exactly)] #[note(lint_learn_more)] #[help] -pub(crate) struct ClashingFunctionNamesWithFundamentalFunctions { +pub(crate) struct RedefiningRuntimeSymbolsDiag { pub symbol_name: String, } diff --git a/compiler/rustc_lint/src/redefining_runtime_symbols.rs b/compiler/rustc_lint/src/redefining_runtime_symbols.rs new file mode 100644 index 0000000000000..d96c7723f45be --- /dev/null +++ b/compiler/rustc_lint/src/redefining_runtime_symbols.rs @@ -0,0 +1,72 @@ +use rustc_hir as hir; +use rustc_session::{declare_lint, declare_lint_pass}; + +use crate::lints::RedefiningRuntimeSymbolsDiag; +use crate::{LateContext, LateLintPass, LintContext}; + +declare_lint! { + /// The `redefining_runtime_symbols` lint checks for items whose symbol name redefines + /// a runtime symbols expected by `core` and/or `std`. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// #![deny(redefining_runtime_symbols)] + /// + /// #[unsafe(no_mangle)] + /// pub fn strlen() {} // redefines the libc `strlen` function + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Up-most care is required when redefining runtime symbols assumed and + /// used by the standard library. They must follow the C specification, not use any + /// standard-library facility or undefined behavior may occur. + /// + /// The symbols currently checked are respectively: + /// - from `core`[^1]: `memcpy`, `memmove`, `memset`, `memcmp`, `bcmp`, `strlen` + /// - from `std`: `read`, `write`, `open`, `close` + /// + /// [^1]: https://doc.rust-lang.org/core/index.html#how-to-use-the-core-library + pub REDEFINING_RUNTIME_SYMBOLS, + Warn, + "redefining a symbol used by the standard library" +} + +declare_lint_pass!(RedefiningRuntimeSymbols => [REDEFINING_RUNTIME_SYMBOLS]); + +static CORE_RUNTIME_SYMBOLS: &[&str] = &["memcpy", "memmove", "memset", "memcmp", "bcmp", "strlen"]; + +static STD_RUNTIME_SYMBOLS: &[&str] = &["open", "read", "write", "close"]; + +impl<'tcx> LateLintPass<'tcx> for RedefiningRuntimeSymbols { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { + // Bail-out if the item is not a function/method or static. + match item.kind { + hir::ItemKind::Fn { sig: _, ident: _, generics: _, body: _, has_body: true } + | hir::ItemKind::Static(..) => {} + _ => return, + } + + // Compute the symbol name of our item (without mangling, as our mangling cannot ever + // conflict with runtime symbols). + let Some(symbol_name) = rustc_symbol_mangling::symbol_name_without_mangling( + cx.tcx, + rustc_middle::ty::InstanceKind::Item(item.owner_id.to_def_id()), + ) else { + return; + }; + + if CORE_RUNTIME_SYMBOLS.contains(&&*symbol_name) + || STD_RUNTIME_SYMBOLS.contains(&&*symbol_name) + { + cx.emit_span_lint( + REDEFINING_RUNTIME_SYMBOLS, + item.span, + RedefiningRuntimeSymbolsDiag { symbol_name }, + ); + } + } +} diff --git a/tests/ui/lint/clashing-fn-names-with-fundamental-functions.stderr b/tests/ui/lint/clashing-fn-names-with-fundamental-functions.stderr deleted file mode 100644 index 55fe4e5eb1e85..0000000000000 --- a/tests/ui/lint/clashing-fn-names-with-fundamental-functions.stderr +++ /dev/null @@ -1,107 +0,0 @@ -warning: this function symbol name `memcpy` clashes with the fundamental functions expected with `core` and `std` - --> $DIR/clashing-fn-names-with-fundamental-functions.rs:9:1 - | -LL | / pub extern "C" fn memcpy( -LL | | dest: *mut c_void, -LL | | src: *const c_void, -LL | | n: i64, -LL | | ) -> *mut c_void { std::ptr::null_mut() } - | |_________________________________________^ - | - = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) - = note: see for the more details - = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "memcpy")]` if present - = note: `#[warn(clashing_function_names_with_fundamental_functions)]` on by default - -warning: this function symbol name `memmove` clashes with the fundamental functions expected with `core` and `std` - --> $DIR/clashing-fn-names-with-fundamental-functions.rs:17:1 - | -LL | pub fn memmove() {} - | ^^^^^^^^^^^^^^^^^^^ - | - = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) - = note: see for the more details - = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "memmove")]` if present - -warning: this function symbol name `memset` clashes with the fundamental functions expected with `core` and `std` - --> $DIR/clashing-fn-names-with-fundamental-functions.rs:21:1 - | -LL | pub fn memset() {} - | ^^^^^^^^^^^^^^^^^^ - | - = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) - = note: see for the more details - = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "memset")]` if present - -warning: this function symbol name `memcmp` clashes with the fundamental functions expected with `core` and `std` - --> $DIR/clashing-fn-names-with-fundamental-functions.rs:25:1 - | -LL | pub fn memcmp() {} - | ^^^^^^^^^^^^^^^^^^ - | - = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) - = note: see for the more details - = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "memcmp")]` if present - -warning: this function symbol name `bcmp` clashes with the fundamental functions expected with `core` and `std` - --> $DIR/clashing-fn-names-with-fundamental-functions.rs:29:1 - | -LL | pub fn bcmp_() {} - | ^^^^^^^^^^^^^^^^^ - | - = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) - = note: see for the more details - = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "bcmp")]` if present - -warning: this function symbol name `strlen` clashes with the fundamental functions expected with `core` and `std` - --> $DIR/clashing-fn-names-with-fundamental-functions.rs:33:1 - | -LL | pub fn strlen() {} - | ^^^^^^^^^^^^^^^^^^ - | - = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) - = note: see for the more details - = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "strlen")]` if present - -warning: this function symbol name `open` clashes with the fundamental functions expected with `core` and `std` - --> $DIR/clashing-fn-names-with-fundamental-functions.rs:39:1 - | -LL | pub fn open() {} - | ^^^^^^^^^^^^^^^^ - | - = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) - = note: see for the more details - = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "open")]` if present - -warning: this function symbol name `read` clashes with the fundamental functions expected with `core` and `std` - --> $DIR/clashing-fn-names-with-fundamental-functions.rs:43:1 - | -LL | pub async fn read1() {} - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) - = note: see for the more details - = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "read")]` if present - -warning: this function symbol name `write` clashes with the fundamental functions expected with `core` and `std` - --> $DIR/clashing-fn-names-with-fundamental-functions.rs:47:1 - | -LL | pub fn write1() {} - | ^^^^^^^^^^^^^^^^^^ - | - = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) - = note: see for the more details - = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "write")]` if present - -warning: this function symbol name `close` clashes with the fundamental functions expected with `core` and `std` - --> $DIR/clashing-fn-names-with-fundamental-functions.rs:51:1 - | -LL | pub fn close_() {} - | ^^^^^^^^^^^^^^^^^^ - | - = note: extra care must be taken when exposing a function with those symbol names, they must match exactly (ABI, function arguments, function return type, behavior, ...) - = note: see for the more details - = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "close")]` if present - -warning: 10 warnings emitted - diff --git a/tests/ui/lint/clashing-fn-names-with-fundamental-functions.rs b/tests/ui/lint/redefining-runtime-symbols.rs similarity index 53% rename from tests/ui/lint/clashing-fn-names-with-fundamental-functions.rs rename to tests/ui/lint/redefining-runtime-symbols.rs index c52f432981188..d5905cecaf30e 100644 --- a/tests/ui/lint/clashing-fn-names-with-fundamental-functions.rs +++ b/tests/ui/lint/redefining-runtime-symbols.rs @@ -11,45 +11,45 @@ pub extern "C" fn memcpy( src: *const c_void, n: i64, ) -> *mut c_void { std::ptr::null_mut() } -//~^^^^^ WARN `memcpy` clashes +//~^^^^^ WARN redefinition of the runtime `memcpy` symbol #[no_mangle] pub fn memmove() {} -//~^ WARN `memmove` clashes +//~^ WARN redefinition of the runtime `memmove` symbol #[no_mangle] pub fn memset() {} -//~^ WARN `memset` clashes +//~^ WARN redefinition of the runtime `memset` symbol #[no_mangle] pub fn memcmp() {} -//~^ WARN `memcmp` clashes +//~^ WARN redefinition of the runtime `memcmp` symbol #[export_name = "bcmp"] pub fn bcmp_() {} -//~^ WARN `bcmp` clashes +//~^ WARN redefinition of the runtime `bcmp` symbol #[no_mangle] -pub fn strlen() {} -//~^ WARN `strlen` clashes +pub static strlen: () = (); +//~^ WARN redefinition of the runtime `strlen` symbol // From std #[no_mangle] pub fn open() {} -//~^ WARN `open` clashes +//~^ WARN redefinition of the runtime `open` symbol #[export_name = "read"] pub async fn read1() {} -//~^ WARN `read` clashes +//~^ WARN redefinition of the runtime `read` symbol #[export_name = "write"] pub fn write1() {} -//~^ WARN `write` clashes +//~^ WARN redefinition of the runtime `write` symbol #[export_name = "close"] pub fn close_() {} -//~^ WARN `close` clashes +//~^ WARN redefinition of the runtime `close` symbol extern "C" { // No warning, not a body. diff --git a/tests/ui/lint/redefining-runtime-symbols.stderr b/tests/ui/lint/redefining-runtime-symbols.stderr new file mode 100644 index 0000000000000..abbae75b01bd9 --- /dev/null +++ b/tests/ui/lint/redefining-runtime-symbols.stderr @@ -0,0 +1,107 @@ +warning: redefinition of the runtime `memcpy` symbol used by the standard library + --> $DIR/redefining-runtime-symbols.rs:9:1 + | +LL | / pub extern "C" fn memcpy( +LL | | dest: *mut c_void, +LL | | src: *const c_void, +LL | | n: i64, +LL | | ) -> *mut c_void { std::ptr::null_mut() } + | |_________________________________________^ + | + = note: extra care must be taken when redefining those symbols, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "memcpy")]` + = note: `#[warn(redefining_runtime_symbols)]` on by default + +warning: redefinition of the runtime `memmove` symbol used by the standard library + --> $DIR/redefining-runtime-symbols.rs:17:1 + | +LL | pub fn memmove() {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when redefining those symbols, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "memmove")]` + +warning: redefinition of the runtime `memset` symbol used by the standard library + --> $DIR/redefining-runtime-symbols.rs:21:1 + | +LL | pub fn memset() {} + | ^^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when redefining those symbols, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "memset")]` + +warning: redefinition of the runtime `memcmp` symbol used by the standard library + --> $DIR/redefining-runtime-symbols.rs:25:1 + | +LL | pub fn memcmp() {} + | ^^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when redefining those symbols, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "memcmp")]` + +warning: redefinition of the runtime `bcmp` symbol used by the standard library + --> $DIR/redefining-runtime-symbols.rs:29:1 + | +LL | pub fn bcmp_() {} + | ^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when redefining those symbols, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "bcmp")]` + +warning: redefinition of the runtime `strlen` symbol used by the standard library + --> $DIR/redefining-runtime-symbols.rs:33:1 + | +LL | pub static strlen: () = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when redefining those symbols, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "strlen")]` + +warning: redefinition of the runtime `open` symbol used by the standard library + --> $DIR/redefining-runtime-symbols.rs:39:1 + | +LL | pub fn open() {} + | ^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when redefining those symbols, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "open")]` + +warning: redefinition of the runtime `read` symbol used by the standard library + --> $DIR/redefining-runtime-symbols.rs:43:1 + | +LL | pub async fn read1() {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when redefining those symbols, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "read")]` + +warning: redefinition of the runtime `write` symbol used by the standard library + --> $DIR/redefining-runtime-symbols.rs:47:1 + | +LL | pub fn write1() {} + | ^^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when redefining those symbols, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "write")]` + +warning: redefinition of the runtime `close` symbol used by the standard library + --> $DIR/redefining-runtime-symbols.rs:51:1 + | +LL | pub fn close_() {} + | ^^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when redefining those symbols, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "close")]` + +warning: 10 warnings emitted + From 03aa60ccce4a1dc8d4f9a3794c97fdde33d74b44 Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 15 Sep 2025 18:01:22 +0200 Subject: [PATCH 3/3] Add `open64` and rename `symbol_name_without_mangling` --- .../src/redefining_runtime_symbols.rs | 6 +++--- compiler/rustc_symbol_mangling/src/lib.rs | 4 ++-- tests/ui/lint/redefining-runtime-symbols.rs | 4 ++++ .../ui/lint/redefining-runtime-symbols.stderr | 18 ++++++++++++++---- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_lint/src/redefining_runtime_symbols.rs b/compiler/rustc_lint/src/redefining_runtime_symbols.rs index d96c7723f45be..450ab0981b16b 100644 --- a/compiler/rustc_lint/src/redefining_runtime_symbols.rs +++ b/compiler/rustc_lint/src/redefining_runtime_symbols.rs @@ -27,7 +27,7 @@ declare_lint! { /// /// The symbols currently checked are respectively: /// - from `core`[^1]: `memcpy`, `memmove`, `memset`, `memcmp`, `bcmp`, `strlen` - /// - from `std`: `read`, `write`, `open`, `close` + /// - from `std`: `open`/`open64`, `read`, `write`, `close` /// /// [^1]: https://doc.rust-lang.org/core/index.html#how-to-use-the-core-library pub REDEFINING_RUNTIME_SYMBOLS, @@ -39,7 +39,7 @@ declare_lint_pass!(RedefiningRuntimeSymbols => [REDEFINING_RUNTIME_SYMBOLS]); static CORE_RUNTIME_SYMBOLS: &[&str] = &["memcpy", "memmove", "memset", "memcmp", "bcmp", "strlen"]; -static STD_RUNTIME_SYMBOLS: &[&str] = &["open", "read", "write", "close"]; +static STD_RUNTIME_SYMBOLS: &[&str] = &["open", "open64", "read", "write", "close"]; impl<'tcx> LateLintPass<'tcx> for RedefiningRuntimeSymbols { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { @@ -52,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for RedefiningRuntimeSymbols { // Compute the symbol name of our item (without mangling, as our mangling cannot ever // conflict with runtime symbols). - let Some(symbol_name) = rustc_symbol_mangling::symbol_name_without_mangling( + let Some(symbol_name) = rustc_symbol_mangling::symbol_name_from_attrs( cx.tcx, rustc_middle::ty::InstanceKind::Item(item.owner_id.to_def_id()), ) else { diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index a3092177c5c17..76e3d29317263 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -158,7 +158,7 @@ pub fn typeid_for_trait_ref<'tcx>( v0::mangle_typeid_for_trait_ref(tcx, trait_ref) } -pub fn symbol_name_without_mangling<'tcx>( +pub fn symbol_name_from_attrs<'tcx>( tcx: TyCtxt<'tcx>, instance_kind: InstanceKind<'tcx>, ) -> Option { @@ -252,7 +252,7 @@ fn compute_symbol_name<'tcx>( debug!("symbol_name(def_id={:?}, args={:?})", def_id, args); - if let Some(symbol) = symbol_name_without_mangling(tcx, instance.def) { + if let Some(symbol) = symbol_name_from_attrs(tcx, instance.def) { return symbol; } diff --git a/tests/ui/lint/redefining-runtime-symbols.rs b/tests/ui/lint/redefining-runtime-symbols.rs index d5905cecaf30e..25f433fc77c00 100644 --- a/tests/ui/lint/redefining-runtime-symbols.rs +++ b/tests/ui/lint/redefining-runtime-symbols.rs @@ -39,6 +39,10 @@ pub static strlen: () = (); pub fn open() {} //~^ WARN redefinition of the runtime `open` symbol +#[no_mangle] +pub fn open64() {} +//~^ WARN redefinition of the runtime `open64` symbol + #[export_name = "read"] pub async fn read1() {} //~^ WARN redefinition of the runtime `read` symbol diff --git a/tests/ui/lint/redefining-runtime-symbols.stderr b/tests/ui/lint/redefining-runtime-symbols.stderr index abbae75b01bd9..ae4314c98a0b2 100644 --- a/tests/ui/lint/redefining-runtime-symbols.stderr +++ b/tests/ui/lint/redefining-runtime-symbols.stderr @@ -73,9 +73,19 @@ LL | pub fn open() {} = note: see for the more details = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "open")]` -warning: redefinition of the runtime `read` symbol used by the standard library +warning: redefinition of the runtime `open64` symbol used by the standard library --> $DIR/redefining-runtime-symbols.rs:43:1 | +LL | pub fn open64() {} + | ^^^^^^^^^^^^^^^^^^ + | + = note: extra care must be taken when redefining those symbols, they must match exactly (ABI, function arguments, function return type, behavior, ...) + = note: see for the more details + = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "open64")]` + +warning: redefinition of the runtime `read` symbol used by the standard library + --> $DIR/redefining-runtime-symbols.rs:47:1 + | LL | pub async fn read1() {} | ^^^^^^^^^^^^^^^^^^^^^^^ | @@ -84,7 +94,7 @@ LL | pub async fn read1() {} = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "read")]` warning: redefinition of the runtime `write` symbol used by the standard library - --> $DIR/redefining-runtime-symbols.rs:47:1 + --> $DIR/redefining-runtime-symbols.rs:51:1 | LL | pub fn write1() {} | ^^^^^^^^^^^^^^^^^^ @@ -94,7 +104,7 @@ LL | pub fn write1() {} = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "write")]` warning: redefinition of the runtime `close` symbol used by the standard library - --> $DIR/redefining-runtime-symbols.rs:51:1 + --> $DIR/redefining-runtime-symbols.rs:55:1 | LL | pub fn close_() {} | ^^^^^^^^^^^^^^^^^^ @@ -103,5 +113,5 @@ LL | pub fn close_() {} = note: see for the more details = help: either allow this lint or remove any `#[unsafe(no_mangle)]` or `#[unsafe(export_name = "close")]` -warning: 10 warnings emitted +warning: 11 warnings emitted