add c-variadic function definitions - #2177
Conversation
| > [!WARNING] | ||
| > Passing an unexpected number of arguments or arguments of unexpected type to a variadic function may lead to [undefined behavior][undefined]. |
There was a problem hiding this comment.
copied from
basically, the responsibility for passing valid arguments is on the caller.
…-in-deps, r=mati865 report the `varargs_without_pattern` lint in deps tracking issue: rust-lang#44930 After discussion in rust-lang/reference#2177 (comment). Based on rust-lang#143619 (comment) there was only one actual impacted crate https://crates.io/crates/binrw. The issue was fixed in jam1garner/binrw#342, and has since been released jam1garner/binrw#342 (comment). Hence we may as well report this loudly. r? @ghost
…-in-deps, r=mati865 report the `varargs_without_pattern` lint in deps tracking issue: rust-lang#44930 After discussion in rust-lang/reference#2177 (comment). Based on rust-lang#143619 (comment) there was only one actual impacted crate https://crates.io/crates/binrw. The issue was fixed in jam1garner/binrw#342, and has since been released jam1garner/binrw#342 (comment). Hence we may as well report this loudly. r? @ghost
…-in-deps, r=mati865 report the `varargs_without_pattern` lint in deps tracking issue: rust-lang#44930 After discussion in rust-lang/reference#2177 (comment). Based on rust-lang#143619 (comment) there was only one actual impacted crate https://crates.io/crates/binrw. The issue was fixed in jam1garner/binrw#342, and has since been released jam1garner/binrw#342 (comment). Hence we may as well report this loudly. r? @ghost
Rollup merge of #154599 - folkertdev:varargs-without-pattern-in-deps, r=mati865 report the `varargs_without_pattern` lint in deps tracking issue: #44930 After discussion in rust-lang/reference#2177 (comment). Based on #143619 (comment) there was only one actual impacted crate https://crates.io/crates/binrw. The issue was fixed in jam1garner/binrw#342, and has since been released jam1garner/binrw#342 (comment). Hence we may as well report this loudly. r? @ghost
|
The I've pushed some tweaks, I'm now planning to submit a stabilization PR in coming days, so if you could look at this again that would be helpful. |
|
It looks like from rust-lang/rust#155974 that there is an intent to make this unavailable on certain targets. I don't think we've ever done something like that, and I'm not sure how we're going to document that. I suppose there will be a rule. It will need to be careful to distinguish that it is a compile error during validation. Unfortunately we don't define that as a specific phase in the reference, so I'm not sure how we should approach that. |
|
I don't think this is very different from https://doc.rust-lang.org/beta/unstable-book/language-features/asm-experimental-arch.html. Consequently the page on inline assembly specifies https://doc.rust-lang.org/nightly/reference/inline-assembly.html?highlight=assemb#r-asm.stable-targets. So we could have
Also spirv and bpf just fundamentally do not support this feature, so there you'd always get an error. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| - x86 and x86-64 | ||
| - ARM | ||
| - AArch64 and Arm64EC | ||
| - RISC-V (except when using the ilp32e ABI) | ||
| - LoongArch | ||
| - s390x | ||
| - PowerPC and PowerPC64 | ||
| - AmdGpu and Nvptx64 | ||
| - wasm32 and wasm64 | ||
| - csky | ||
| - xtensa | ||
| - hexagon | ||
| - sparc64 | ||
| - mips |
There was a problem hiding this comment.
Nit: This mixes lowercase with the arches' name casing (C-SKY, Xtensa, Hexagon, SPARC64, MIPS, Wasm). Also some platforms are explicit about both 32- and 64-bit (x86, ppc) while others aren't (loongarch, mips)
There was a problem hiding this comment.
It is based on the list of stable architectures for asm!, I've tried to correct the names.
There was a problem hiding this comment.
The merge of the stabilization PR is now only blocked on the additions to the reference here (I'm not sure that is really needed, previously features have been merged with a reference PR that was "far enough along").
I've tried to address comments here as much possible now.
I'd be happy to look at this together in the reference office hours if they are at a somewhat european-friendly time.
| - x86 and x86-64 | ||
| - ARM | ||
| - AArch64 and Arm64EC | ||
| - RISC-V (except when using the ilp32e ABI) | ||
| - LoongArch | ||
| - s390x | ||
| - PowerPC and PowerPC64 | ||
| - AmdGpu and Nvptx64 | ||
| - wasm32 and wasm64 | ||
| - csky | ||
| - xtensa | ||
| - hexagon | ||
| - sparc64 | ||
| - mips |
There was a problem hiding this comment.
It is based on the list of stable architectures for asm!, I've tried to correct the names.
It's a bit complicated which declarations are required to be `unsafe` when using variadic argument lists; let's enumerate the cases.
88338f3 to
d8b62a8
Compare
The statement that the "lifetime of a `VaList` is that of the function (call) that created it" feels a bit loose to me. Let's pin that down more precisely.
We're moving in the direction of having one or more examples for each rule where possible. Let's add examples to the new rules where they were missing and make sense to have.
The pattern is required when the variadic parameter appears either on a function definition or on a function declaration in a trait definition. Let's say that and add examples.
Though we document that function definitions and associated function declarations in trait definitions must have a pattern, that's only true due to an FCW. Let's add an admonition about that.
| ```rust,compile_fail | ||
| unsafe extern "C" fn f(...) {} // ERROR: Missing pattern. | ||
| ``` | ||
|
|
||
| ```rust,compile_fail | ||
| trait Tr { | ||
| unsafe extern "C" fn f(...); // ERROR: Missing pattern. | ||
| } | ||
| ``` | ||
|
|
||
| > [!NOTE] | ||
| > `rustc` currently accepts `...` without a pattern in function definitions and associated function declarations in trait definitions while linting against it. This will become an error in the future. | ||
| > | ||
| > ```rust | ||
| > #![allow(varargs_without_pattern)] | ||
| > unsafe extern "C" fn f(...) {} // OK. | ||
| > ``` | ||
| > | ||
| > ```rust | ||
| > #![allow(varargs_without_pattern)] | ||
| > trait Tr { | ||
| > unsafe extern "C" fn f(...); // OK. | ||
| > } | ||
| > ``` |
There was a problem hiding this comment.
In adding these examples, I realized that the rule here is only enforced by a lint. Is that intended? Since C-variadic function definitions were not previously accepted on stable Rust, it would be more ordinary to give a hard error here rather than stabilizing something and immediately linting against it.
There was a problem hiding this comment.
Hmm, we could maybe deny it later in the pipeline (so in hir validation)? The goal of the FCW is to eventually deny ... in that position pre-expansion, which would be a breaking change.
We semantically did not accept c-variadic definitions so far, but syntactically we actually did, and macros could (and did) make use of that syntactic freedom.
There was a problem hiding this comment.
That is my inclination. Filed as rust-lang/rust#160109.
There was a problem hiding this comment.
Discussed in the lang meeting, this will be resolved by rust-lang/rust#160165.
|
@rustbot label -S-waiting-on-stabilization Stabilization merged in rust-lang/rust#155697 |
Co-authored-by: Daniel Scherzer <daniel.e.scherzer@gmail.com>
| r[items.fn.c-variadic.abi] | ||
| Only `extern "C"` and `extern "C-unwind"` function definitions can accept a variable argument list. | ||
|
|
||
| ```rust,compile_fail | ||
| unsafe fn f(ap: ...) {} // ERROR: Not supported. | ||
| ``` | ||
|
|
||
| ```rust,compile_fail | ||
| unsafe extern "sysv64" fn f(ap: ...) {} // ERROR: Not supported. | ||
| ``` |
There was a problem hiding this comment.
Now that c_variadic_naked_functions (rust-lang/rust#159746) is in FCP, this section needs to be extended. Do we just do that now, wait for FCP to be over, or do it in a separate PR?
I was thinking of something like this:
A variable argument list is only accepted on [naked functions] for the ABI strings that are listed in [items.extern.variadic.conventions].
```rust
#[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
"#,
)
}
```
[items.extern.variadic.conventions]: ../items/external-blocks.md#items.extern.variadic.conventions
[naked functions]: ../attributes.md#attributes.codegen.naked
I think this has all of the raw material, but needs polishing.
Here is a draft of the stabilization report, for additional context: https://hackmd.io/@Q66MPiW4T7yNTKOCaEb-Lw/S1iI3WIwZg
Tracking issue: rust-lang/rust#44930
Stabilization: