Skip to content

implement feature(c_variadic_naked_functions) - #148770

Merged
bors merged 3 commits into
rust-lang:mainfrom
folkertdev:naked-c-variadic
Nov 12, 2025
Merged

implement feature(c_variadic_naked_functions)#148770
bors merged 3 commits into
rust-lang:mainfrom
folkertdev:naked-c-variadic

Conversation

@folkertdev

@folkertdev folkertdev commented Nov 9, 2025

Copy link
Copy Markdown
Contributor

tracking issue: #148767

#t-lang > C-variadic naked functions

This feature allows naked c-variadic function definitions with any ABI that is supported for foreign c-variadic functions.

#![feature(c_variadic, c_variadic_naked_functions)]

#[unsafe(naked)]
unsafe extern "win64" fn variadic_win64(_: u32, _: ...) -> u32 {
    core::arch::naked_asm!(
        r#"
        push    rax
        mov     qword ptr [rsp + 40], r9
        mov     qword ptr [rsp + 24], rdx
        mov     qword ptr [rsp + 32], r8
        lea     rax, [rsp + 40]
        mov     qword ptr [rsp], rax
        lea     eax, [rdx + rcx]
        add     eax, r8d
        pop     rcx
        ret
    "#,
    )
}

r? @workingjubilee

@folkertdev folkertdev added A-naked Area: `#[naked]`, prologue and epilogue-free, functions, https://git.io/vAzzS F-c_variadic `#![feature(c_variadic)]` labels Nov 9, 2025
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 9, 2025
@rustbot

rustbot commented Nov 9, 2025

Copy link
Copy Markdown
Collaborator

workingjubilee is currently at their maximum review capacity.
They may take a while to respond.

@workingjubilee

Copy link
Copy Markdown
Member

ferris_aware

@workingjubilee

Copy link
Copy Markdown
Member

seems fine.

@bors r+ rollup

@bors

bors commented Nov 11, 2025

Copy link
Copy Markdown
Collaborator

📌 Commit 9129b90 has been approved by workingjubilee

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 11, 2025
Zalathar added a commit to Zalathar/rust that referenced this pull request Nov 11, 2025
…kingjubilee

implement `feature(c_variadic_naked_functions)`

tracking issue: rust-lang#148767

[#t-lang > C-variadic naked functions](https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/C-variadic.20naked.20functions/with/554593886)

This feature allows naked c-variadic function definitions with any ABI that is supported for foreign c-variadic functions.

```rust
#![feature(c_variadic, c_variadic_naked_functions)]

#[unsafe(naked)]
unsafe extern "win64" fn variadic_win64(_: u32, _: ...) -> u32 {
    core::arch::naked_asm!(
        r#"
        push    rax
        mov     qword ptr [rsp + 40], r9
        mov     qword ptr [rsp + 24], rdx
        mov     qword ptr [rsp + 32], r8
        lea     rax, [rsp + 40]
        mov     qword ptr [rsp], rax
        lea     eax, [rdx + rcx]
        add     eax, r8d
        pop     rcx
        ret
    "#,
    )
}
```

r? `@workingjubilee`
Zalathar added a commit to Zalathar/rust that referenced this pull request Nov 11, 2025
…kingjubilee

implement `feature(c_variadic_naked_functions)`

tracking issue: rust-lang#148767

[#t-lang > C-variadic naked functions](https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/C-variadic.20naked.20functions/with/554593886)

This feature allows naked c-variadic function definitions with any ABI that is supported for foreign c-variadic functions.

```rust
#![feature(c_variadic, c_variadic_naked_functions)]

#[unsafe(naked)]
unsafe extern "win64" fn variadic_win64(_: u32, _: ...) -> u32 {
    core::arch::naked_asm!(
        r#"
        push    rax
        mov     qword ptr [rsp + 40], r9
        mov     qword ptr [rsp + 24], rdx
        mov     qword ptr [rsp + 32], r8
        lea     rax, [rsp + 40]
        mov     qword ptr [rsp], rax
        lea     eax, [rdx + rcx]
        add     eax, r8d
        pop     rcx
        ret
    "#,
    )
}
```

r? ``@workingjubilee``
bors added a commit that referenced this pull request Nov 12, 2025
Rollup of 12 pull requests

Successful merges:

 - #146627 (Simplify `jemalloc` setup)
 - #147753 (Suggest add bounding value for RangeTo)
 - #147974 (Improve diagnostics for buffer reuse with borrowed references)
 - #148080 ([rustdoc] Fix invalid jump to def macro link generation)
 - #148424 (bootstrap: Add snapshot tests for path-to-step handling)
 - #148500 (Update git index before running diff-index)
 - #148536 (cmse: add test for `async` and `const` functions)
 - #148770 (implement `feature(c_variadic_naked_functions)`)
 - #148819 (Remove specialized warning for removed target)
 - #148830 (miri subtree update)
 - #148833 (Update rustbook dependencies)
 - #148841 (Remove more `#[must_use]` from portable-simd)

r? `@ghost`
`@rustbot` modify labels: rollup
Zalathar added a commit to Zalathar/rust that referenced this pull request Nov 12, 2025
…kingjubilee

implement `feature(c_variadic_naked_functions)`

tracking issue: rust-lang#148767

[#t-lang > C-variadic naked functions](https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/C-variadic.20naked.20functions/with/554593886)

This feature allows naked c-variadic function definitions with any ABI that is supported for foreign c-variadic functions.

```rust
#![feature(c_variadic, c_variadic_naked_functions)]

#[unsafe(naked)]
unsafe extern "win64" fn variadic_win64(_: u32, _: ...) -> u32 {
    core::arch::naked_asm!(
        r#"
        push    rax
        mov     qword ptr [rsp + 40], r9
        mov     qword ptr [rsp + 24], rdx
        mov     qword ptr [rsp + 32], r8
        lea     rax, [rsp + 40]
        mov     qword ptr [rsp], rax
        lea     eax, [rdx + rcx]
        add     eax, r8d
        pop     rcx
        ret
    "#,
    )
}
```

r? ```@workingjubilee```
bors added a commit that referenced this pull request Nov 12, 2025
Rollup of 16 pull requests

Successful merges:

 - #146627 (Simplify `jemalloc` setup)
 - #147753 (Suggest add bounding value for RangeTo)
 - #147832 (rustdoc: Don't pass `RenderOptions` to `DocContext`)
 - #147974 (Improve diagnostics for buffer reuse with borrowed references)
 - #148080 ([rustdoc] Fix invalid jump to def macro link generation)
 - #148465 (Adjust spans into the `for` loops context before creating the new desugaring spans.)
 - #148500 (Update git index before running diff-index)
 - #148531 (rustc_target: introduce Abi, Env, Os)
 - #148536 (cmse: add test for `async` and `const` functions)
 - #148770 (implement `feature(c_variadic_naked_functions)`)
 - #148780 (fix filecheck typos in tests)
 - #148819 (Remove specialized warning for removed target)
 - #148830 (miri subtree update)
 - #148833 (Update rustbook dependencies)
 - #148834 (fix(rustdoc): Color doctest errors)
 - #148841 (Remove more `#[must_use]` from portable-simd)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors
bors merged commit 60b2068 into rust-lang:main Nov 12, 2025
11 checks passed
@rustbot rustbot added this to the 1.93.0 milestone Nov 12, 2025
rust-timer added a commit that referenced this pull request Nov 12, 2025
Rollup merge of #148770 - folkertdev:naked-c-variadic, r=workingjubilee

implement `feature(c_variadic_naked_functions)`

tracking issue: #148767

[#t-lang > C-variadic naked functions](https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/C-variadic.20naked.20functions/with/554593886)

This feature allows naked c-variadic function definitions with any ABI that is supported for foreign c-variadic functions.

```rust
#![feature(c_variadic, c_variadic_naked_functions)]

#[unsafe(naked)]
unsafe extern "win64" fn variadic_win64(_: u32, _: ...) -> u32 {
    core::arch::naked_asm!(
        r#"
        push    rax
        mov     qword ptr [rsp + 40], r9
        mov     qword ptr [rsp + 24], rdx
        mov     qword ptr [rsp + 32], r8
        lea     rax, [rsp + 40]
        mov     qword ptr [rsp], rax
        lea     eax, [rdx + rcx]
        add     eax, r8d
        pop     rcx
        ret
    "#,
    )
}
```

r? ````@workingjubilee````
github-actions Bot pushed a commit to rust-lang/miri that referenced this pull request Nov 12, 2025
Rollup of 16 pull requests

Successful merges:

 - rust-lang/rust#146627 (Simplify `jemalloc` setup)
 - rust-lang/rust#147753 (Suggest add bounding value for RangeTo)
 - rust-lang/rust#147832 (rustdoc: Don't pass `RenderOptions` to `DocContext`)
 - rust-lang/rust#147974 (Improve diagnostics for buffer reuse with borrowed references)
 - rust-lang/rust#148080 ([rustdoc] Fix invalid jump to def macro link generation)
 - rust-lang/rust#148465 (Adjust spans into the `for` loops context before creating the new desugaring spans.)
 - rust-lang/rust#148500 (Update git index before running diff-index)
 - rust-lang/rust#148531 (rustc_target: introduce Abi, Env, Os)
 - rust-lang/rust#148536 (cmse: add test for `async` and `const` functions)
 - rust-lang/rust#148770 (implement `feature(c_variadic_naked_functions)`)
 - rust-lang/rust#148780 (fix filecheck typos in tests)
 - rust-lang/rust#148819 (Remove specialized warning for removed target)
 - rust-lang/rust#148830 (miri subtree update)
 - rust-lang/rust#148833 (Update rustbook dependencies)
 - rust-lang/rust#148834 (fix(rustdoc): Color doctest errors)
 - rust-lang/rust#148841 (Remove more `#[must_use]` from portable-simd)

r? `@ghost`
`@rustbot` modify labels: rollup
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 29, 2025
Rollup of 16 pull requests

Successful merges:

 - rust-lang/rust#146627 (Simplify `jemalloc` setup)
 - rust-lang/rust#147753 (Suggest add bounding value for RangeTo)
 - rust-lang/rust#147832 (rustdoc: Don't pass `RenderOptions` to `DocContext`)
 - rust-lang/rust#147974 (Improve diagnostics for buffer reuse with borrowed references)
 - rust-lang/rust#148080 ([rustdoc] Fix invalid jump to def macro link generation)
 - rust-lang/rust#148465 (Adjust spans into the `for` loops context before creating the new desugaring spans.)
 - rust-lang/rust#148500 (Update git index before running diff-index)
 - rust-lang/rust#148531 (rustc_target: introduce Abi, Env, Os)
 - rust-lang/rust#148536 (cmse: add test for `async` and `const` functions)
 - rust-lang/rust#148770 (implement `feature(c_variadic_naked_functions)`)
 - rust-lang/rust#148780 (fix filecheck typos in tests)
 - rust-lang/rust#148819 (Remove specialized warning for removed target)
 - rust-lang/rust#148830 (miri subtree update)
 - rust-lang/rust#148833 (Update rustbook dependencies)
 - rust-lang/rust#148834 (fix(rustdoc): Color doctest errors)
 - rust-lang/rust#148841 (Remove more `#[must_use]` from portable-simd)

r? `@ghost`
`@rustbot` modify labels: rollup
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
Rollup of 16 pull requests

Successful merges:

 - rust-lang/rust#146627 (Simplify `jemalloc` setup)
 - rust-lang/rust#147753 (Suggest add bounding value for RangeTo)
 - rust-lang/rust#147832 (rustdoc: Don't pass `RenderOptions` to `DocContext`)
 - rust-lang/rust#147974 (Improve diagnostics for buffer reuse with borrowed references)
 - rust-lang/rust#148080 ([rustdoc] Fix invalid jump to def macro link generation)
 - rust-lang/rust#148465 (Adjust spans into the `for` loops context before creating the new desugaring spans.)
 - rust-lang/rust#148500 (Update git index before running diff-index)
 - rust-lang/rust#148531 (rustc_target: introduce Abi, Env, Os)
 - rust-lang/rust#148536 (cmse: add test for `async` and `const` functions)
 - rust-lang/rust#148770 (implement `feature(c_variadic_naked_functions)`)
 - rust-lang/rust#148780 (fix filecheck typos in tests)
 - rust-lang/rust#148819 (Remove specialized warning for removed target)
 - rust-lang/rust#148830 (miri subtree update)
 - rust-lang/rust#148833 (Update rustbook dependencies)
 - rust-lang/rust#148834 (fix(rustdoc): Color doctest errors)
 - rust-lang/rust#148841 (Remove more `#[must_use]` from portable-simd)

r? `@ghost`
`@rustbot` modify labels: rollup
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
Rollup of 16 pull requests

Successful merges:

 - rust-lang/rust#146627 (Simplify `jemalloc` setup)
 - rust-lang/rust#147753 (Suggest add bounding value for RangeTo)
 - rust-lang/rust#147832 (rustdoc: Don't pass `RenderOptions` to `DocContext`)
 - rust-lang/rust#147974 (Improve diagnostics for buffer reuse with borrowed references)
 - rust-lang/rust#148080 ([rustdoc] Fix invalid jump to def macro link generation)
 - rust-lang/rust#148465 (Adjust spans into the `for` loops context before creating the new desugaring spans.)
 - rust-lang/rust#148500 (Update git index before running diff-index)
 - rust-lang/rust#148531 (rustc_target: introduce Abi, Env, Os)
 - rust-lang/rust#148536 (cmse: add test for `async` and `const` functions)
 - rust-lang/rust#148770 (implement `feature(c_variadic_naked_functions)`)
 - rust-lang/rust#148780 (fix filecheck typos in tests)
 - rust-lang/rust#148819 (Remove specialized warning for removed target)
 - rust-lang/rust#148830 (miri subtree update)
 - rust-lang/rust#148833 (Update rustbook dependencies)
 - rust-lang/rust#148834 (fix(rustdoc): Color doctest errors)
 - rust-lang/rust#148841 (Remove more `#[must_use]` from portable-simd)

r? `@ghost`
`@rustbot` modify labels: rollup
Kobzol pushed a commit to Kobzol/portable-simd that referenced this pull request Feb 3, 2026
Rollup of 16 pull requests

Successful merges:

 - rust-lang/rust#146627 (Simplify `jemalloc` setup)
 - rust-lang/rust#147753 (Suggest add bounding value for RangeTo)
 - rust-lang/rust#147832 (rustdoc: Don't pass `RenderOptions` to `DocContext`)
 - rust-lang/rust#147974 (Improve diagnostics for buffer reuse with borrowed references)
 - rust-lang/rust#148080 ([rustdoc] Fix invalid jump to def macro link generation)
 - rust-lang/rust#148465 (Adjust spans into the `for` loops context before creating the new desugaring spans.)
 - rust-lang/rust#148500 (Update git index before running diff-index)
 - rust-lang/rust#148531 (rustc_target: introduce Abi, Env, Os)
 - rust-lang/rust#148536 (cmse: add test for `async` and `const` functions)
 - rust-lang/rust#148770 (implement `feature(c_variadic_naked_functions)`)
 - rust-lang/rust#148780 (fix filecheck typos in tests)
 - rust-lang/rust#148819 (Remove specialized warning for removed target)
 - rust-lang/rust#148830 (miri subtree update)
 - rust-lang/rust#148833 (Update rustbook dependencies)
 - rust-lang/rust#148834 (fix(rustdoc): Color doctest errors)
 - rust-lang/rust#148841 (Remove more `#[must_use]` from portable-simd)

r? `@ghost`
`@rustbot` modify labels: rollup
Kobzol pushed a commit to Kobzol/portable-simd that referenced this pull request Feb 3, 2026
Rollup of 16 pull requests

Successful merges:

 - rust-lang/rust#146627 (Simplify `jemalloc` setup)
 - rust-lang/rust#147753 (Suggest add bounding value for RangeTo)
 - rust-lang/rust#147832 (rustdoc: Don't pass `RenderOptions` to `DocContext`)
 - rust-lang/rust#147974 (Improve diagnostics for buffer reuse with borrowed references)
 - rust-lang/rust#148080 ([rustdoc] Fix invalid jump to def macro link generation)
 - rust-lang/rust#148465 (Adjust spans into the `for` loops context before creating the new desugaring spans.)
 - rust-lang/rust#148500 (Update git index before running diff-index)
 - rust-lang/rust#148531 (rustc_target: introduce Abi, Env, Os)
 - rust-lang/rust#148536 (cmse: add test for `async` and `const` functions)
 - rust-lang/rust#148770 (implement `feature(c_variadic_naked_functions)`)
 - rust-lang/rust#148780 (fix filecheck typos in tests)
 - rust-lang/rust#148819 (Remove specialized warning for removed target)
 - rust-lang/rust#148830 (miri subtree update)
 - rust-lang/rust#148833 (Update rustbook dependencies)
 - rust-lang/rust#148834 (fix(rustdoc): Color doctest errors)
 - rust-lang/rust#148841 (Remove more `#[must_use]` from portable-simd)

r? `@ghost`
`@rustbot` modify labels: rollup
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 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-naked Area: `#[naked]`, prologue and epilogue-free, functions, https://git.io/vAzzS F-c_variadic `#![feature(c_variadic)]` S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants