-
Notifications
You must be signed in to change notification settings - Fork 13.4k
C-variadic functions must be unsafe #141733
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
C-variadic functions must be unsafe #141733
Conversation
r? @nnethercote rustbot has assigned @nnethercote. Use |
27bb41f
to
2bab33c
Compare
tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs
Outdated
Show resolved
Hide resolved
tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr
Outdated
Show resolved
Hide resolved
@folkertdev This seems semantically reasonable to me, with a lang hat on. I posted a few comments on the implementation. With those fixed, the implementation looks reasonable to me, but I'm not a compiler reviewer, so someone else should take a look at the implementation. |
c02225d
to
c31ba7b
Compare
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.
Looks good, a couple of tiny nits to fix, then r=me.
@bors delegate=folkertdev
@@ -83,3 +83,8 @@ trait T { | |||
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg | |||
//~| ERROR `...` must be the last argument of a C-variadic function | |||
} | |||
|
|||
unsafe extern "C" { | |||
safe fn s_f1(...); |
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.
Given that this is machine applicable, it would be good to have one or two examples with longer signatures containing additional arguments. A printf-style signature would be a good example.
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.
(And how did I get this far without knowing that safe
was a keyword?)
c067ed5
to
604a56b
Compare
This comment has been minimized.
This comment has been minimized.
604a56b
to
30ddd3c
Compare
The job Click to see the possible cause of the failure (guessed by this bot)
|
@folkertdev: 🔑 Insufficient privileges: Not in reviewers |
hmm, apparently closing/reopening (to get CI to re-run) removes the delegation. Anyway, I think this is ready. |
@bors r+ |
…y-speed, r=nnethercote C-variadic functions must be unsafe tracking issue: rust-lang#44930 A function that uses `...` is always unsafe to call, because it is UB to provide the wrong number of arguments, or arguments of an unexpected type. Hence, an `unsafe extern "C" { /* ... */ }` block should not be able to declare a `safe fn` that uses `...`. cc `@joshtriplett` `@workingjubilee` I'm not really sure who'd be a good reviewer for the actual parser code. `@rustbot` label: +F-c_variadic
Rollup of 6 pull requests Successful merges: - #140715 (Clarify &mut-methods' docs on sync::OnceLock) - #141309 (x86 (32/64): go back to passing SIMD vectors by-ptr) - #141677 (Async drop - type instead of async drop fn, fixes #140484) - #141733 (C-variadic functions must be unsafe) - #141858 (Fix typo in `StructuralPartialEq` docs) - #141874 (add f16_epsilon and f128_epsilon diagnostic items) r? `@ghost` `@rustbot` modify labels: rollup
…y-speed, r=nnethercote C-variadic functions must be unsafe tracking issue: rust-lang#44930 A function that uses `...` is always unsafe to call, because it is UB to provide the wrong number of arguments, or arguments of an unexpected type. Hence, an `unsafe extern "C" { /* ... */ }` block should not be able to declare a `safe fn` that uses `...`. cc ``@joshtriplett`` ``@workingjubilee`` I'm not really sure who'd be a good reviewer for the actual parser code. ``@rustbot`` label: +F-c_variadic
…y-speed, r=nnethercote C-variadic functions must be unsafe tracking issue: rust-lang#44930 A function that uses `...` is always unsafe to call, because it is UB to provide the wrong number of arguments, or arguments of an unexpected type. Hence, an `unsafe extern "C" { /* ... */ }` block should not be able to declare a `safe fn` that uses `...`. cc ```@joshtriplett``` ```@workingjubilee``` I'm not really sure who'd be a good reviewer for the actual parser code. ```@rustbot``` label: +F-c_variadic
Isn't this a breaking change? Can we go through something closer to our regular processes for doing that? |
Actually, yes. I think this is straightforward though. I propose to error on the following construction, that declares a function using C variadic arguments as unsafe extern "C" {
safe fn printf(format: *const u8, ...);
} This seems like an oversight from when I suspect, because @rustbot label +I-lang-nominated +I-lang-easy-decision |
Except for our documentation. Can you please send a PR to update https://github.com/rust-lang/reference/blob/master/src/items/external-blocks.md#variadic-functions with a more suitable example? |
And then send a second PR that would add a new rule for this restriction. |
@bors r- |
@rustbot labels -I-lang-easy-decision This turned out to not be an easy decision. More details from discussion to come. |
We discussed this in today's @rust-lang/lang meeting. Several people raised the point that calling a C varargs function is safe if you never look at the arguments, which technically makes it "library UB", not "language UB". On all targets I'm aware of, this property holds; I've pinged @Amanieu for additional review and confirmation for current and anticipated future targets. Given this, lang does not want to prohibit this at the language level. Several of us were amenable to a lint, though we didn't attempt to establish consensus on that in this meeting, and would need to confirm that before someone should invest any efforts in writing one. |
Fun edge case. Assuming there are no weird targets where never looking at the arguments is still UB, as a user I'd expect the reference to at least make a note on this (that |
It's in scope for a non-normative admonition, e.g. |
With rust-lang/reference#1839 merged I think we're done here. |
tracking issue: #44930
A function that uses
...
is always unsafe to call, because it is UB to provide the wrong number of arguments, or arguments of an unexpected type. Hence, anunsafe extern "C" { /* ... */ }
block should not be able to declare asafe fn
that uses...
.cc @joshtriplett @workingjubilee
I'm not really sure who'd be a good reviewer for the actual parser code.
@rustbot label: +F-c_variadic