-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Tracking Issue for RFC #2972: Constrained Naked Functions #90957
Comments
"produce a clear warning if any of the above suggestions are not heeded" in RFC seems to contain typo |
This is implemented, checking the box. Adding a new step: "Confirm that all errors and warnings are emitted properly". |
Request for StabilizationA proposal that the SummaryAdds a new attribute, The body of a naked function must consist of a single An example of a naked function: const THREE: usize = 3;
#[naked]
/// Adds three to a number and returns the result.
pub extern "sysv64" fn add_n(number: usize) -> usize {
// SAFETY: the validity of these registers is guaranteed according to the "sysv64" ABI
unsafe {
std::arch::asm!(
"add rdi, {}",
"mov rax, rdi",
"ret",
const THREE,
options(noreturn)
);
}
} DocumentationThe Rust Reference: rust-lang/reference#1153 Tests
HistoryThis feature was originally proposed in RFC 1201, filed on 2015-07-10 and accepted on 2016-03-21. Support for this feature was added in #32410, landing on 2016-03-23. Development languished for several years as it was realized that the semantics given in RFC 1201 were insufficiently specific. To address this, a minimal subset of naked functions was specified by RFC 2972, filed on 2020-08-07 and accepted on 2021-11-16. Prior to the acceptance of RFC 2972, all of the stricter behavior specified by RFC 2972 was implemented as a series of warn-by-default lints that would trigger on existing uses of the Unresolved Questions
|
This stabilizes the feature described in RFC 2972, which supersedes the earlier RFC 1201. Closes rust-lang#32408 Closes rust-lang#90957
There is no observable difference between LLVM adding an epilogue and a following unnamed function starting with instructions identical to a regular epilogue. |
@bjorn3 I believe it can cause problems in circumstances such as #32408 (comment) . If someone were to work around that issue by assuming the existence of extra instructions and manually accounting for it, then their code would be broken if Rust ever stopped generating those instructions. It is this sort of edge case that this defensive wording is designed to address. |
I believe it's possible to observe a difference when |
👍 for stabilizing, though I'd like to make sure that there's consensus on #32408 (comment) . |
Shall we stabilize constrained naked functions? @rfcbot merge |
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
I'd like to have a whitelist of attributes that are allowed to be applies to a naked function. In the future we may want to lower naked functions directly to LLVM module-level assembly instead of using LLVM's native naked function support. For that to happen rustc needs to be able to manually translate any attributes (e.g. |
Why, because of the epilogue issue? Personally I would much rather see that fixed on LLVM’s end, rather than going to great lengths to work around it in rustc. Or is there another reason? |
Lowering to |
@comex In addition to the epilogue issue, it seems the inlining issue could also be resolved by lowering to @Amanieu I'd be interested in seeing such a list. Obviously part of the appeal of naked functions is that they can be treated just like a normal function in most cases, which includes the ability to be marked with attributes (e.g. |
Most attributes that work with arbitrary functions should work with naked functions IMO. Taking the list here, those make sense to use with naked fns:
The only ones that I think make sense to disallow are those in the "Code Generation" category:
|
…isibility, r=bjorn3 add test for symbol visibility of `#[naked]` functions tracking issue: rust-lang#90957 This test is extracted from rust-lang#128004 That PR attempts to generated naked functions as an extern function declaration, combined with a global asm block that provides the implementation for that declaration. In order to link declaration and definition together, some flavor of external linking must be used: LLVM will error for other linkage types. Specifically the allowed options are `#[linkage = "external"]` and `#[linkage = "extern_weak"]`. That is kind of an implementation detail though: to the user, a naked function should just behave like a normal function. Hence it should be visible to the linker under the same circumstances as a normal, vanilla function and have the same attributes (Weak, External). Getting this behavior right will require some care, so I think it's a good idea to lock it in now, before making any changes, to make sure we don't regress. Are there any interesting cases that I missed here? E.g. is checking on different architectures worth it? I don't think the other binary types (rlib etc) are relevant here, but may be missing something. r? ``@bjorn3``
…isibility, r=bjorn3 add test for symbol visibility of `#[naked]` functions tracking issue: rust-lang#90957 This test is extracted from rust-lang#128004 That PR attempts to generated naked functions as an extern function declaration, combined with a global asm block that provides the implementation for that declaration. In order to link declaration and definition together, some flavor of external linking must be used: LLVM will error for other linkage types. Specifically the allowed options are `#[linkage = "external"]` and `#[linkage = "extern_weak"]`. That is kind of an implementation detail though: to the user, a naked function should just behave like a normal function. Hence it should be visible to the linker under the same circumstances as a normal, vanilla function and have the same attributes (Weak, External). Getting this behavior right will require some care, so I think it's a good idea to lock it in now, before making any changes, to make sure we don't regress. Are there any interesting cases that I missed here? E.g. is checking on different architectures worth it? I don't think the other binary types (rlib etc) are relevant here, but may be missing something. r? `@bjorn3`
…isibility, r=bjorn3 add test for symbol visibility of `#[naked]` functions tracking issue: rust-lang#90957 This test is extracted from rust-lang#128004 That PR attempts to generated naked functions as an extern function declaration, combined with a global asm block that provides the implementation for that declaration. In order to link declaration and definition together, some flavor of external linking must be used: LLVM will error for other linkage types. Specifically the allowed options are `#[linkage = "external"]` and `#[linkage = "extern_weak"]`. That is kind of an implementation detail though: to the user, a naked function should just behave like a normal function. Hence it should be visible to the linker under the same circumstances as a normal, vanilla function and have the same attributes (Weak, External). Getting this behavior right will require some care, so I think it's a good idea to lock it in now, before making any changes, to make sure we don't regress. Are there any interesting cases that I missed here? E.g. is checking on different architectures worth it? I don't think the other binary types (rlib etc) are relevant here, but may be missing something. r? ``@bjorn3``
…ibility, r=<try> add test for symbol visibility of `#[naked]` functions tracking issue: rust-lang#90957 This test is extracted from rust-lang#128004 That PR attempts to generated naked functions as an extern function declaration, combined with a global asm block that provides the implementation for that declaration. In order to link declaration and definition together, some flavor of external linking must be used: LLVM will error for other linkage types. Specifically the allowed options are `#[linkage = "external"]` and `#[linkage = "extern_weak"]`. That is kind of an implementation detail though: to the user, a naked function should just behave like a normal function. Hence it should be visible to the linker under the same circumstances as a normal, vanilla function and have the same attributes (Weak, External). Getting this behavior right will require some care, so I think it's a good idea to lock it in now, before making any changes, to make sure we don't regress. Are there any interesting cases that I missed here? E.g. is checking on different architectures worth it? I don't think the other binary types (rlib etc) are relevant here, but may be missing something. r? `@bjorn3` try-job: x86_64-msvc try-job: i686-msvc
…ibility, r=<try> add test for symbol visibility of `#[naked]` functions tracking issue: rust-lang#90957 This test is extracted from rust-lang#128004 That PR attempts to generated naked functions as an extern function declaration, combined with a global asm block that provides the implementation for that declaration. In order to link declaration and definition together, some flavor of external linking must be used: LLVM will error for other linkage types. Specifically the allowed options are `#[linkage = "external"]` and `#[linkage = "extern_weak"]`. That is kind of an implementation detail though: to the user, a naked function should just behave like a normal function. Hence it should be visible to the linker under the same circumstances as a normal, vanilla function and have the same attributes (Weak, External). Getting this behavior right will require some care, so I think it's a good idea to lock it in now, before making any changes, to make sure we don't regress. Are there any interesting cases that I missed here? E.g. is checking on different architectures worth it? I don't think the other binary types (rlib etc) are relevant here, but may be missing something. r? `@bjorn3` try-job: x86_64-msvc try-job: i686-msvc try-job: i686-mingw try-job: x86_64-mingw
…isibility, r=bjorn3 add test for symbol visibility of `#[naked]` functions tracking issue: rust-lang#90957 This test is extracted from rust-lang#128004 That PR attempts to generated naked functions as an extern function declaration, combined with a global asm block that provides the implementation for that declaration. In order to link declaration and definition together, some flavor of external linking must be used: LLVM will error for other linkage types. Specifically the allowed options are `#[linkage = "external"]` and `#[linkage = "extern_weak"]`. That is kind of an implementation detail though: to the user, a naked function should just behave like a normal function. Hence it should be visible to the linker under the same circumstances as a normal, vanilla function and have the same attributes (Weak, External). Getting this behavior right will require some care, so I think it's a good idea to lock it in now, before making any changes, to make sure we don't regress. Are there any interesting cases that I missed here? E.g. is checking on different architectures worth it? I don't think the other binary types (rlib etc) are relevant here, but may be missing something. r? `@bjorn3`
…isibility, r=bjorn3 add test for symbol visibility of `#[naked]` functions tracking issue: rust-lang#90957 This test is extracted from rust-lang#128004 That PR attempts to generated naked functions as an extern function declaration, combined with a global asm block that provides the implementation for that declaration. In order to link declaration and definition together, some flavor of external linking must be used: LLVM will error for other linkage types. Specifically the allowed options are `#[linkage = "external"]` and `#[linkage = "extern_weak"]`. That is kind of an implementation detail though: to the user, a naked function should just behave like a normal function. Hence it should be visible to the linker under the same circumstances as a normal, vanilla function and have the same attributes (Weak, External). Getting this behavior right will require some care, so I think it's a good idea to lock it in now, before making any changes, to make sure we don't regress. Are there any interesting cases that I missed here? E.g. is checking on different architectures worth it? I don't think the other binary types (rlib etc) are relevant here, but may be missing something. r? ``@bjorn3``
Rollup merge of rust-lang#128362 - folkertdev:naked-function-symbol-visibility, r=bjorn3 add test for symbol visibility of `#[naked]` functions tracking issue: rust-lang#90957 This test is extracted from rust-lang#128004 That PR attempts to generated naked functions as an extern function declaration, combined with a global asm block that provides the implementation for that declaration. In order to link declaration and definition together, some flavor of external linking must be used: LLVM will error for other linkage types. Specifically the allowed options are `#[linkage = "external"]` and `#[linkage = "extern_weak"]`. That is kind of an implementation detail though: to the user, a naked function should just behave like a normal function. Hence it should be visible to the linker under the same circumstances as a normal, vanilla function and have the same attributes (Weak, External). Getting this behavior right will require some care, so I think it's a good idea to lock it in now, before making any changes, to make sure we don't regress. Are there any interesting cases that I missed here? E.g. is checking on different architectures worth it? I don't think the other binary types (rlib etc) are relevant here, but may be missing something. r? ``@bjorn3``
As a procedural question, I'd like to ask whether the stablization FCP above is still valid, given it's been ~2 years since it finished. |
…tions, r=workingjubilee,compiler-errors add repr to the allowlist for naked functions Fixes rust-lang#129412 (combining unstable features rust-lang#90957 (`#![feature(naked_functions)]`) and rust-lang#82232 (`#![feature(fn_align)]`)
Rollup merge of rust-lang#129421 - jdonszelmann:naked-repr-align-functions, r=workingjubilee,compiler-errors add repr to the allowlist for naked functions Fixes rust-lang#129412 (combining unstable features rust-lang#90957 (`#![feature(naked_functions)]`) and rust-lang#82232 (`#![feature(fn_align)]`)
That is an awfully long time ago. Please |
sure @rustbot label +I-lang-nominated for context, recent changes mostly implement changes suggested by @Amanieu. The main changes are
So far this design (still) looks good to me |
@rustbot labels -I-lang-nominated @folkertdev: When I said please nominate the PR for stabilization, what I mean is, please make a pull request that stabilizes this feature (if you're ready to do that) (documentation here). In that PR, please include a stabilization report. You can start from the one here and update it with what has changed since then and why it's ready to stabilize now. Then please nominate that PR for lang. |
…Amanieu bootstrap `naked_asm!` for `compiler-builtins` tracking issue: rust-lang#90957 parent PR: rust-lang#128651 in this PR, `naked_asm!` is added as an alias for `asm!` with one difference: `options(noreturn)` is always enabled by `naked_asm!`. That makes it future-compatible for when `naked_asm!` starts disallowing `options(noreturn)` later. The `naked_asm!` macro must be introduced first so that we can upgrade `compiler-builtins` to use it, and can then change the implementation of `naked_asm!` in rust-lang#128651 I've added some usages for `naked_asm!` in the tests, so we can be confident that it works, but I've left upgrading the whole test suite to the parent PR. r? `@Amanieu`
…Amanieu bootstrap `naked_asm!` for `compiler-builtins` tracking issue: rust-lang#90957 parent PR: rust-lang#128651 in this PR, `naked_asm!` is added as an alias for `asm!` with one difference: `options(noreturn)` is always enabled by `naked_asm!`. That makes it future-compatible for when `naked_asm!` starts disallowing `options(noreturn)` later. The `naked_asm!` macro must be introduced first so that we can upgrade `compiler-builtins` to use it, and can then change the implementation of `naked_asm!` in rust-lang#128651 I've added some usages for `naked_asm!` in the tests, so we can be confident that it works, but I've left upgrading the whole test suite to the parent PR. r? ``@Amanieu``
Rollup merge of rust-lang#130146 - folkertdev:bootstrap-naked-asm, r=Amanieu bootstrap `naked_asm!` for `compiler-builtins` tracking issue: rust-lang#90957 parent PR: rust-lang#128651 in this PR, `naked_asm!` is added as an alias for `asm!` with one difference: `options(noreturn)` is always enabled by `naked_asm!`. That makes it future-compatible for when `naked_asm!` starts disallowing `options(noreturn)` later. The `naked_asm!` macro must be introduced first so that we can upgrade `compiler-builtins` to use it, and can then change the implementation of `naked_asm!` in rust-lang#128651 I've added some usages for `naked_asm!` in the tests, so we can be confident that it works, but I've left upgrading the whole test suite to the parent PR. r? ``@Amanieu``
…n, r=<try> disallow `naked_asm!` outside of `#[naked]` functions tracking issue: rust-lang#90957 parent PR: rust-lang#128651 I split this out from the parent PR because it's self-contained and because the analysis has to search through all functions and there might be performance regressions. r? `@Amanieu`
bootstrap `naked_asm!` for `compiler-builtins` tracking issue: rust-lang/rust#90957 parent PR: rust-lang/rust#128651 in this PR, `naked_asm!` is added as an alias for `asm!` with one difference: `options(noreturn)` is always enabled by `naked_asm!`. That makes it future-compatible for when `naked_asm!` starts disallowing `options(noreturn)` later. The `naked_asm!` macro must be introduced first so that we can upgrade `compiler-builtins` to use it, and can then change the implementation of `naked_asm!` in rust-lang/rust#128651 I've added some usages for `naked_asm!` in the tests, so we can be confident that it works, but I've left upgrading the whole test suite to the parent PR. r? ``@Amanieu``
…n, r=Amanieu disallow `naked_asm!` outside of `#[naked]` functions tracking issue: rust-lang#90957 parent PR: rust-lang#128651 I split this out from the parent PR because it's self-contained and because the analysis has to search through all functions and there might be performance regressions. r? `@Amanieu`
disallow `naked_asm!` outside of `#[naked]` functions tracking issue: rust-lang/rust#90957 parent PR: rust-lang/rust#128651 I split this out from the parent PR because it's self-contained and because the analysis has to search through all functions and there might be performance regressions. r? `@Amanieu`
…nieu add `naked_asm!` macro for use in `#[naked]` functions tracking issue: rust-lang#90957 Adds the `core::arch::naked_asm` macro, to be used in `#[naked]` functions, but providing better error messages and a place to explain the restrictions on assembly in naked functions. This PR does not yet require that the `naked_asm!` macro is used inside of `#[naked]` functions: - the `asm!` macro can still be used in `#[naked]` functions currently, with the same restrictions and error messages as before. - the `naked_asm!` macro can be used outside of `#[naked]` functions. It has not yet been decided whether that should be allowed long-term. In this PR, the parsing code of `naked_asm!` now enforces the restrictions on assembly in naked functions, with the exception of checking that the `noreturn` option is specified. It also has not currently been decided if `noreturn` should be implicit or not. This PR looks large because it touches a bunch of tests. The code changes are mostly straightforward I think: we now have 3 flavors of assembly macro, and that information must be propagated through the parsing code and error messages. cc `@Lokathor` r? `@Amanieu`
This is a tracking issue for the RFC "Constrained Naked Functions" (rust-lang/rfcs#2972).
The feature gate for the issue is
#![feature(naked_functions)]
.About tracking issues
Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
Steps
#[naked]
Unresolved Questions
None.
Implementation history
The text was updated successfully, but these errors were encountered: