document naked c-variadic functions - #2321
Open
folkertdev wants to merge 8 commits into
Open
Conversation
For the link definition for "naked functions", let's use the rule identifier. For `items.extern.variadic.conventions`, we don't need a link definition since the link text is the full rule identifier.
We use "naked functions" twice in a single rule. Let's link the first use of this rather than the second. (There would be some logic, here, in linking the second since the first use is an exclusion while the second is defining something for these, but it's better to follow our convention.)
Let's restate this sentence in the active voice. This is clearer and better parallels the preceding rule.
For this example, rather than showing raw compiler output, which contains a spill-and-reload sequence that is hard to follow, let's write some assembly by hand. And let's pick an example that motivates the use of variadics. We'll compute the dot product of a vector with a projected scalar. We'll support vector dimensions up to what can be passed in with the `xmm` registers.
The rule says a naked function's ABI string must be "listed in" another rule. But that rule lists some ABI strings and then separately accepts their `-unwind` variants. We mean to accept everything the other rule accepts. Let's say "accepted under" instead.
traviscross
approved these changes
Aug 9, 2026
JonathanBrouwer
added a commit
to JonathanBrouwer/rust
that referenced
this pull request
Aug 9, 2026
…ked-functions, r=tiif stabilize `c_variadic_naked_functions` tracking issue: rust-lang#148767 reference PR: rust-lang/reference#2321 # Stabilization report ## Summary Stabilize the ability to use `#[unsafe(naked)]` functions to define c-variadic functions. These c-variadic naked functions accept the same set of ABIs as c-variadic foreign functions, this set is larger than what we currently accept for c-variadic definitions. ```rust #[unsafe(naked)] unsafe extern "aapcs" fn variadic_aapcs(_: f64, _: ...) -> f64 { core::arch::naked_asm!( r#" sub sp, sp, rust-lang#12 stmib sp, {{r2, r3}} vmov d0, r0, r1 add r0, sp, rust-lang#4 vldr d1, [sp, rust-lang#4] add r0, r0, rust-lang#15 bic r0, r0, rust-lang#7 vadd.f64 d0, d0, d1 add r1, r0, rust-lang#8 str r1, [sp] vldr d1, [r0] vadd.f64 d0, d0, d1 vmov r0, r1, d0 add sp, sp, rust-lang#12 bx lr "#, ) } ``` ## Accepted ABIs The set of accepted ABIs is the same as for c-variadic foreign functions, defined as rule [`items.extern.variadic.conventions`](https://doc.rust-lang.org/nightly/reference/items/external-blocks.html?highlight=externblo#r-items.extern.variadic.conventions): - `"aapcs"` - `"C"` - `"cdecl"` - `"efiapi"` - `"system"` - `"sysv64"` - `"win64"` And their corresponding `-unwind` variants. Given that naked functions desugar to a block of module assembly and a foreign definition, it makes sense to support the same set as source-level foreign definitions. For c-variadic definitions we only accept `"C"` and `"C-unwind"`. ## Multiple c-variadic ABIs in the same program LLVM supports c-variadic calls of different ABIs in the same program. We test both an arm and x86 configuration - https://github.com/rust-lang/rust/blob/771916f9028e7fe56d2685f2c4f698de5d7d6a45/tests/ui/c-variadic/same-program-multiple-abis-arm.rs - https://github.com/rust-lang/rust/blob/771916f9028e7fe56d2685f2c4f698de5d7d6a45/tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs Note that GCC, Clang and LLVM do not support c-variadic definitions of multiple ABIs: the `va_start`, `va_arg` etc. macros are always expanded using the default C calling convention. Clang and GCC reject a variable argument list on definitions that use a non-default calling convention. ## History - [#t-lang > C-variadic naked functions](https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/C-variadic.20naked.20functions/with/554593886) - rust-lang#148770 The stabilization report of `feature(c_variadic)` mentions this feature: - rust-lang#155697 ## Unresolved questions None.
JonathanBrouwer
added a commit
to JonathanBrouwer/rust
that referenced
this pull request
Aug 9, 2026
…ked-functions, r=tiif stabilize `c_variadic_naked_functions` tracking issue: rust-lang#148767 reference PR: rust-lang/reference#2321 # Stabilization report ## Summary Stabilize the ability to use `#[unsafe(naked)]` functions to define c-variadic functions. These c-variadic naked functions accept the same set of ABIs as c-variadic foreign functions, this set is larger than what we currently accept for c-variadic definitions. ```rust #[unsafe(naked)] unsafe extern "aapcs" fn variadic_aapcs(_: f64, _: ...) -> f64 { core::arch::naked_asm!( r#" sub sp, sp, rust-lang#12 stmib sp, {{r2, r3}} vmov d0, r0, r1 add r0, sp, rust-lang#4 vldr d1, [sp, rust-lang#4] add r0, r0, rust-lang#15 bic r0, r0, rust-lang#7 vadd.f64 d0, d0, d1 add r1, r0, rust-lang#8 str r1, [sp] vldr d1, [r0] vadd.f64 d0, d0, d1 vmov r0, r1, d0 add sp, sp, rust-lang#12 bx lr "#, ) } ``` ## Accepted ABIs The set of accepted ABIs is the same as for c-variadic foreign functions, defined as rule [`items.extern.variadic.conventions`](https://doc.rust-lang.org/nightly/reference/items/external-blocks.html?highlight=externblo#r-items.extern.variadic.conventions): - `"aapcs"` - `"C"` - `"cdecl"` - `"efiapi"` - `"system"` - `"sysv64"` - `"win64"` And their corresponding `-unwind` variants. Given that naked functions desugar to a block of module assembly and a foreign definition, it makes sense to support the same set as source-level foreign definitions. For c-variadic definitions we only accept `"C"` and `"C-unwind"`. ## Multiple c-variadic ABIs in the same program LLVM supports c-variadic calls of different ABIs in the same program. We test both an arm and x86 configuration - https://github.com/rust-lang/rust/blob/771916f9028e7fe56d2685f2c4f698de5d7d6a45/tests/ui/c-variadic/same-program-multiple-abis-arm.rs - https://github.com/rust-lang/rust/blob/771916f9028e7fe56d2685f2c4f698de5d7d6a45/tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs Note that GCC, Clang and LLVM do not support c-variadic definitions of multiple ABIs: the `va_start`, `va_arg` etc. macros are always expanded using the default C calling convention. Clang and GCC reject a variable argument list on definitions that use a non-default calling convention. ## History - [#t-lang > C-variadic naked functions](https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/C-variadic.20naked.20functions/with/554593886) - rust-lang#148770 The stabilization report of `feature(c_variadic)` mentions this feature: - rust-lang#155697 ## Unresolved questions None.
rust-timer
added a commit
to rust-lang/rust
that referenced
this pull request
Aug 9, 2026
Rollup merge of #159746 - folkertdev:stabilize-c-variadic-naked-functions, r=tiif stabilize `c_variadic_naked_functions` tracking issue: #148767 reference PR: rust-lang/reference#2321 # Stabilization report ## Summary Stabilize the ability to use `#[unsafe(naked)]` functions to define c-variadic functions. These c-variadic naked functions accept the same set of ABIs as c-variadic foreign functions, this set is larger than what we currently accept for c-variadic definitions. ```rust #[unsafe(naked)] unsafe extern "aapcs" fn variadic_aapcs(_: f64, _: ...) -> f64 { core::arch::naked_asm!( r#" sub sp, sp, #12 stmib sp, {{r2, r3}} vmov d0, r0, r1 add r0, sp, #4 vldr d1, [sp, #4] add r0, r0, #15 bic r0, r0, #7 vadd.f64 d0, d0, d1 add r1, r0, #8 str r1, [sp] vldr d1, [r0] vadd.f64 d0, d0, d1 vmov r0, r1, d0 add sp, sp, #12 bx lr "#, ) } ``` ## Accepted ABIs The set of accepted ABIs is the same as for c-variadic foreign functions, defined as rule [`items.extern.variadic.conventions`](https://doc.rust-lang.org/nightly/reference/items/external-blocks.html?highlight=externblo#r-items.extern.variadic.conventions): - `"aapcs"` - `"C"` - `"cdecl"` - `"efiapi"` - `"system"` - `"sysv64"` - `"win64"` And their corresponding `-unwind` variants. Given that naked functions desugar to a block of module assembly and a foreign definition, it makes sense to support the same set as source-level foreign definitions. For c-variadic definitions we only accept `"C"` and `"C-unwind"`. ## Multiple c-variadic ABIs in the same program LLVM supports c-variadic calls of different ABIs in the same program. We test both an arm and x86 configuration - https://github.com/rust-lang/rust/blob/771916f9028e7fe56d2685f2c4f698de5d7d6a45/tests/ui/c-variadic/same-program-multiple-abis-arm.rs - https://github.com/rust-lang/rust/blob/771916f9028e7fe56d2685f2c4f698de5d7d6a45/tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs Note that GCC, Clang and LLVM do not support c-variadic definitions of multiple ABIs: the `va_start`, `va_arg` etc. macros are always expanded using the default C calling convention. Clang and GCC reject a variable argument list on definitions that use a non-default calling convention. ## History - [#t-lang > C-variadic naked functions](https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/C-variadic.20naked.20functions/with/554593886) - #148770 The stabilization report of `feature(c_variadic)` mentions this feature: - #155697 ## Unresolved questions None.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A first draft. I'm not sure what the right way is to draw a distinction between function definition and naked function definition.
Stabilization:
c_variadic_naked_functionsrust#159746