Implement RFC 2945: "C-unwind" ABI #76570
Conversation
|
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @varkor (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
0a0146d to
8839990
Compare
|
r? @Amanieu |
|
☔ The latest upstream changes (presumably #76582) made this pull request unmergeable. Please resolve the merge conflicts. Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels: |
nikomatsakis
left a comment
There was a problem hiding this comment.
Looking good to me so far!
589f2ea to
9925553
Compare
|
Cross-posting from the #project-ffi-unwind zulip channel:
|
nikomatsakis
left a comment
There was a problem hiding this comment.
The changes look good. One thing I am wondering about is when we call C-unwind functions that are implemented in, well, C. In other words, I think we should have a test for the fastly use case, where we invoke a C function that invokes a Rust function which panics, and we test that this panic propagates up the stack. I'm not sure how easy/hard it will be to write such a test though, including C code might be a pain. At minimum we could have a test for panics propagating through Rust functions with C-unwind ABI (and perhaps the same but where those functions are in an auxiliary crate).
(Cross crate tests can be created by using the // aux-build: comments in tests; I didn't find any docs on this, but you can maybe grep around to see how it's done. You basically write // aux-build: foo.rs and then add a file auxiliary/foo.rs. You can then import the crate foo.)
|
For C functions to call, I believe https://github.com/rust-lang/rust/blob/master/src/test/auxiliary/rust_test_helpers.c is the place to add it to -- that file is compiled once and then linked with all UI tests I believe. Or, if you need more complex invocations of C compilers or linkers then run-make tests are the way to go. |
|
Ah, nice. I didn't know about that. |
|
☔ The latest upstream changes (presumably #75671) made this pull request unmergeable. Please resolve the merge conflicts. Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels: |
a7c65d6 to
0bc1754
Compare
|
Providing a small update. These two tests are currently failing, because of an Aside from that, I want to add the tests described in the comments above, and then this should be in good shape. |
|
I've seen both those tests fail locally too when using lld as the linker, so I would check without your PR. It's quite possible that it's unrelated to your work :) |
|
Interesting... it may be the case that |
|
☔ The latest upstream changes (presumably #78837) made this pull request unmergeable. Please resolve the merge conflicts. Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels: |
|
Leaving another note here for posterity... One of the key design goals specified in RFC 2945 is stated as such:
This appears to have already been implemented in 5f1a0af, and has test coverage in |
fde38d6 to
4d2d1d8
Compare
### Changes
This commit implements unwind ABI's, specified in RFC 2945.
We adjust the `rustc_middle::ty::layout::fn_can_unwind` function,
used to compute whether or not a `FnAbi` object represents a
function that should be able to unwind when `panic=unwind` is in
use.
Changes are also made to
`rustc_mir_build::build::should_abort_on_panic` so that the
function ABI is used to determind whether it should abort, assuming
that the `panic=unwind` strategy is being used, and no explicit
unwind attribute was provided.
### Tests
Unit tests, checking that the behavior is correct for `C-unwind`,
`stdcall-unwind`, `system-unwind`, and `thiscall-unwind`, are
included. These alternative `unwind` ABI strings are specified in
RFC 2945, in the "_Other `unwind` ABI strings_" section.
Additionally, a test case is included to assert that the LLVM IR
generated for an external function defined with the `C-unwind` ABI
will be appropriately labeled with the `nounwind` LLVM attribute
when the `panic=abort` compilation flag is used.
### Ignore Directives
This commit uses `ignore-*` directives in two of our `*-unwind` ABI
test cases.
Specifically, the `stdcall-unwind` and `thiscall-unwind` test cases
ignore architectures that do not support `stdcall` and `thiscall`,
respectively.
These directives are cribbed from
`src/test/ui/c-variadic/variadic-ffi-1.rs` for `stdcall`, and
`src/test/ui/extern/extern-thiscall.rs` for `thiscall`.
### Integration Tests
This commit introduces some new fixtures to the `run-make-fulldeps`
test suite.
* c-unwind-abi-catch-panic: Exercise unwinding a panic. This
catches a panic across an FFI boundary and downcasts it into
an integer.
* c-unwind-abi-catch-lib-panic: This is similar to the previous
`*catch-panic` test, however in this case the Rust code that
panics resides in a separate crate.
### Add `rust_eh_personality` to `#[no_std]` alloc tests
This commit addresses some test failures that now occur in the
following two tests:
* no_std-alloc-error-handler-custom.rs
* no_std-alloc-error-handler-default.rs
Each test now defines a `rust_eh_personality` extern function, in
the same manner as shown in the "Writing an executable without
stdlib" section of the `lang_items` documentation here:
https://doc.rust-lang.org/unstable-book/language-features/lang-items.html#writing-an-executable-without-stdlib
Without this change, these tests would fail to compile due to a
linking error explaining that there was an "undefined reference
to `rust_eh_personality'."
### Updated hash
* update 32-bit hash in `impl1` test
### Panics
This commit uses `panic!` macro invocations that return a string,
rather than using an integer as a panic payload.
Doing so avoids the following warnings that were observed during
rollup for the `*-msvc-1` targets:
```
warning: panic message is not a string literal
--> panic.rs:10:16
|
10 | panic!(x); // That is too big!
| ^
|
= note: `#[warn(non_fmt_panic)]` on by default
= note: this is no longer accepted in Rust 2021
help: add a "{}" format string to Display the message
|
10 | panic!("{}", x); // That is too big!
| ^^^^^
help: or use std::panic::panic_any instead
|
10 | std::panic::panic_any(x); // That is too big!
| ^^^^^^^^^^^^^^^^^^^^^
warning: 1 warning emitted
```
See: https://github.com/rust-lang-ci/rust/runs/1992118428
As these errors imply, panicking without a format string will be
disallowed in Rust 2021, per rust-lang#78500.
### Add debug assertion to check `AbiDatas` ordering
This makes a small alteration to `Abi::index`, so that we include a
debug assertion to check that the index we are returning corresponds
with the same abi in our data array.
This will help prevent ordering bugs in the future, which can
manifest in rather strange errors.
### Using exhaustive ABI matches
This slightly modifies the changes from our previous commits,
favoring exhaustive matches in place of `_ => ...` fall-through
arms.
This should help with maintenance in the future, when additional
ABI's are added, or when existing ABI's are modified.
### List all `-unwind` ABI's in unstable book
This updates the `c-unwind` page in the unstable book to list _all_
of the other ABI strings that are introduced by this feature gate.
Now, all of the ABI's specified by RFC 2945 are shown.
Co-authored-by: Amanieu d'Antras <amanieu@gmail.com>
Co-authored-by: Niko Matsakis <niko@alum.mit.edu>
|
Just addressed the merge conflicts that had popped up, pending CI this should be ready for another attempt at ye olde rollup 🍬 🎉 |
|
well.. before the 'ye olde rollup it needs to be r+'d first ;) @bors r=Amanieu |
|
📌 Commit 05bf037 has been approved by |
|
☀️ Test successful - checks-actions |
Implement RFC 2945: "C-unwind" ABI
This branch implements RFC 2945. The tracking issue for this RFC is #74990.
The feature gate for the issue is
#![feature(c_unwind)].This RFC was created as part of the ffi-unwind project group tracked at rust-lang/lang-team#19.
Changes
Further details will be provided in commit messages, but a high-level overview
of the changes follows:
A boolean
unwindpayload is added to theC,System,Stdcall,and
Thiscallvariants, marking whether unwinding across FFI boundaries isacceptable. The cases where each of these variants'
unwindmember is truecorrespond with the
C-unwind,system-unwind,stdcall-unwind, andthiscall-unwindABI strings introduced in RFC 2945 [3].This commit adds a
c_unwindfeature gate for the new ABI strings.Tests for this feature gate are included in
src/test/ui/c-unwind/, whichensure that this feature gate works correctly for each of the new ABIs.
A new language features entry in the unstable book is added as well.
We adjust the
rustc_middle::ty::layout::fn_can_unwindfunction,used to compute whether or not a
FnAbiobject represents a function thatshould be able to unwind when
panic=unwindis in use.Changes are also made to
rustc_mir_build::build::should_abort_on_panicso that the function ABI isused to determind whether it should abort, assuming that the
panic=unwindstrategy is being used, and no explicit unwind attribute was provided.