-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Add lint about redefining runtime symbols #146505
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
base: master
Are you sure you want to change the base?
Conversation
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…<try> Add lint warn about clashing function names with fundamental functions
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (fb73ebd): comparison URL. Overall result: no relevant changes - no action neededBenchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf. @bors rollup=never Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)Results (secondary -0.3%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (secondary -2.6%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 468.794s -> 471.13s (0.50%) |
9943712
to
e2446d7
Compare
These commits modify the If this was unintentional then you should revert the changes before this PR is merged. |
This comment has been minimized.
This comment has been minimized.
To bikeshed the name: I wouldn't call this "clashing" unless the lint is checking specifically that the signature doesn't match what is expected for each symbol. We have an existing I wouldn't refer to "function names" here because a "function name" in Rust refers to the name of the function in Rust rather than to the symbol name, and we want to focus on the symbol name here. Also, shouldn't we be checking for more than just functions? This breaks things too: #[unsafe(no_mangle)]
static read: () = (); I probably wouldn't call these functions "fundamental". Maybe "runtime", "system", "platform", "builtin", "libc", or similar would work. Perhaps |
e2446d7
to
e0952b2
Compare
Indeed, forgot that statics also have a symbol. Fixed. Regarding the lint level, I made it warn-by-default since there are legitimate reasons to implement those symbols (like when implementing a libc), but maybe it should be deny-by-default? |
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; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could just be
if let Some(name) = attrs.symbol_name {
// Use provided name
return name.to_string();
}
if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
// Don't mangle
return tcx.item_name(def_id).to_string();
}
right? The rest of symbol_name_without_mangling
is not relevant here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically yes, but I don't want the logic to be at two different places if we don't have to, and since the perf run is clean as is, I would like to keep symbol_name_without_mangling
(to avoid duplicating the logic).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function name is not entirely correct given that aside from this snippet, all code inside this function handles cases where there actually is symbol mangling because of #[rustc_std_internal_symbol]
, because of #[wasm_import_module]
or because it is the static containing all defined proc macros.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the function name not great. It's should be more something like symbol_name_from_attrs
, not sure what the right name should be.
EDIT: done
/// The symbols currently checked are respectively: | ||
/// - from `core`[^1]: `memcpy`, `memmove`, `memset`, `memcmp`, `bcmp`, `strlen` | ||
/// - 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, | ||
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", "open64", "read", "write", "close"]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the significance of documenting a split between core
and std
? It looks like they get checked the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not very important; it's mainly a way to distinguish between explicitly documented symbols (those in core) and those that are more implicit (those in std).
Regarding the checking, it could be asked to not check the std runtime symbols in #![no_std]
, which I don't think we should do, #![no_std]
crates may still end-up in std-full crates.
This PR adds lint to warn about redefinition of runtime symbols1 that are assumed and used by
core
2 andstd
.We have had multiple reports of users tripping over this:
#[no_mangle] fn open() {}
makecargo t
hang?no_mangle
redefining_runtime_symbols
Old proposed name:
clashing_function_names_with_fundamental_functions
(warn-by-default)
The
redefining_runtime_symbols
lint checks for items whose symbol name redefines a runtime symbols expected bycore
and/orstd
.Example
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:
core
2:memcpy
,memmove
,memset
,memcmp
,bcmp
,strlen
std
:open
/open64
,read
,write
,close
@rustbot labels +I-lang-nominated +T-lang +needs-fcp +A-lints
cc @traviscross
r? compiler
Footnotes
previous lint name
clashing_function_names_with_fundamental_functions
, bike-shed at https://github.com/rust-lang/rust/pull/146505#issuecomment-3288716835 ↩https://doc.rust-lang.org/core/index.html#how-to-use-the-core-library ↩ ↩2