Skip to content
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

move new c abi abort behavior behind feature gate #84158

Merged
merged 1 commit into from
Apr 14, 2021

Conversation

cratelyn
Copy link

Background

In #76570, new ABI strings including C-unwind were introduced. Their
behavior is specified in RFC 2945 1.

However, it was reported in the #ffi-unwind stream of the Rust community Zulip
that this had altered the way that extern "C" functions behaved even when the
c_unwind feature gate was not active. 2

Overview

This makes a small patch to rustc_mir_build::build::should_abort_on_panic, so
that the same behavior from before is in place when the c_unwind gate is not
active.

rustc_middle::ty::layout::fn_can_unwind is not touched, as the visible
behavior should not differ before/after #76570. 3


1: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
2: https://rust-lang.zulipchat.com/#narrow/stream/210922-project-ffi-unwind/topic/Is.20unwinding.20through.20extern.20C.20UB.3F/near/230112325
3: https://github.com/rust-lang/rust/pull/76570/files#diff-b0320c2b8868f325d83c027fc5d71732636e9763551e35895488f30fe057c6e9L2599-R2617

 ### Background

    In rust-lang#76570, new ABI strings including `C-unwind` were introduced.
    Their behavior is specified in RFC 2945 [1].

    However, it was reported in the #ffi-unwind stream of the Rust
    community Zulip that this had altered the way that `extern "C"`
    functions behaved even when the `c_unwind` feature gate was not
    active. [2]

 ### Overview

    This makes a small patch to
    `rustc_mir_build::build::should_abort_on_panic`, so that the same
    behavior from before is in place when the `c_unwind` gate is not
    active.

    `rustc_middle::ty::layout::fn_can_unwind` is not touched, as the
    visible behavior should not differ before/after rust-lang#76570. [3]

 ### Footnotes

 [1]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
 [2]: https://rust-lang.zulipchat.com/#narrow/stream/210922-project-ffi-unwind/topic/Is.20unwinding.20through.20extern.20C.20UB.3F/near/230112325
 [3]: https://github.com/rust-lang/rust/pull/76570/files#diff-b0320c2b8868f325d83c027fc5d71732636e9763551e35895488f30fe057c6e9L2599-R2617
@rust-highfive
Copy link
Collaborator

r? @varkor

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 13, 2021
@BatmanAoD
Copy link
Member

Does rustc_middle::ty::layout::fn_can_unwind control whether the nounwind attribute is emitted? If possible, we should not emit that for "C" when the "C-unwind" feature is not enabled, because it's the source of the UB.

@cratelyn
Copy link
Author

Does rustc_middle::ty::layout::fn_can_unwind control whether the nounwind attribute is emitted? If possible, we should not emit that for "C" when the "C-unwind" feature is not enabled, because it's the source of the UB.

Hi! I want to make sure that we're not mixed up here; I realize the distinctions between "should abort" and "can unwind" are not initially intuitive and aren't quite the direct inverses that I initially believed them to be.

First, to answer your original question, yes rustc_middle::ty::layout::fn_can_unwind controls whether the nounwind attribute is emitted. You can see that happen here specifically, in <FnAbi<'tcx, Ty<'tcx>> as FnAbiLlvmExt<'tcx>>::apply_attrs_llfn.

But, I want to highlight that this UB exists on stable today, unless I'm mistaken. If we take this file...

#![crate_type = "lib"]
pub extern "C" fn huhu() {}

and compile it like so...

$: rustc --version                                                       
rustc 1.51.0 (2fd73fabe 2021-03-23)
$: rustc --edition=2018 --emit=llvm-ir -C opt-level=0 extern-c-example.rs
$: /bin/cat extern-c-example.ll
; ModuleID = 'extern_c_example.3a1fbbbh-cgu.0'
source_filename = "extern_c_example.3a1fbbbh-cgu.0"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; extern_c_example::huhu
; Function Attrs: nounwind nonlazybind uwtable
define void @_ZN16extern_c_example4huhu17h914345848a8b0e88E() unnamed_addr #0 {
start:
  ret void
}

attributes #0 = { nounwind nonlazybind uwtable "probe-stack"="__rust_probestack" "target-cpu"="x86-64" }

!llvm.module.flags = !{!0, !1}

!0 = !{i32 7, !"PIC Level", i32 2}
!1 = !{i32 2, !"RtLibUseGOT", i32 1}

...we'll see the same nounwind. The behavior that's changed in the wake of #76570 is whether or not an extern "C" function will abort on panic, which you can see in this particular part of that diff.

we should not emit that for "C" when the "C-unwind" feature is not enabled, because it's the source of the UB.

So to get to this second part of your question @BatmanAoD, I believe we should keep the nounwind emission the same as it is today, as it matches the current behavior of stable w.r.t extern "C" functions.

Does that make sense?

@BatmanAoD
Copy link
Member

BatmanAoD commented Apr 14, 2021 via email

@nikomatsakis
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Apr 14, 2021

📌 Commit 3e16d23 has been approved by nikomatsakis

@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 Apr 14, 2021
@bors
Copy link
Contributor

bors commented Apr 14, 2021

⌛ Testing commit 3e16d23 with merge 07ef259...

@bors
Copy link
Contributor

bors commented Apr 14, 2021

☀️ Test successful - checks-actions
Approved by: nikomatsakis
Pushing 07ef259 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Apr 14, 2021
@bors bors merged commit 07ef259 into rust-lang:master Apr 14, 2021
@rustbot rustbot added this to the 1.53.0 milestone Apr 14, 2021
@cratelyn cratelyn deleted the patch-extern-c-unwind-behavior branch April 14, 2021 18:48
@pnkfelix pnkfelix added beta-nominated Nominated for backporting to the compiler in the beta channel. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed beta-nominated Nominated for backporting to the compiler in the beta channel. labels Apr 15, 2021
@pnkfelix
Copy link
Member

beta-nominating, because I believe our intention was for this to get into 1.52 in order to avoid bugs like #83541 hitting stable.

@cratelyn
Copy link
Author

Seconding, that was exactly the intention 🙂

ogoffart added a commit to woboq/qmetaobject-rs that referenced this pull request Apr 20, 2021
Beta is currently broken because of rust-lang/rust#84158
@wesleywiser
Copy link
Member

We discussed this in the compiler team triage meeting this morning and the consensus was that we would like to try reverting #76570 on beta first. If that proves complicated, then we will backport this PR instead.

@wesleywiser wesleywiser removed the beta-nominated Nominated for backporting to the compiler in the beta channel. label Apr 22, 2021
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 30, 2021
…t-of-84158, r=Mark-Simulacrum

backport: move new c abi abort behavior behind feature gate

This is a backport of PR rust-lang#84158 to the beta branch.

The original T-compiler plan was to revert PR rust-lang#76570 in its entirety, as was attempted in PR rust-lang#84672. But the revert did not go smoothly (details below).

Therefore, we are backporting PR rust-lang#84158 instead, which was our established backup plan if a revert did not go smoothly.

I have manually confirmed that this backport fixes the luajit issue described on issue rust-lang#83541

<details>

<summary>Click for details as to why revert of PR rust-lang#76570 did not go smoothly.</summary>

It turns out that Miri had been subsequently updated to reflect changes to `rustc_target` that landed in PR rust-lang#76570. This meant that the attempt to land PR rust-lang#84672 broke Miri builds.

Normally we allow tools to break when landing PR's (and just expect follow-up PR's to fix the tools), but we don't allow it for tools in the run-up to a release.

(We shouldn't be using that uniform policy for all tools. Miri should be allow to break during the week before a release; but currently we cannot express that, due to issue rust-lang#74709.)

Therefore, its a lot of pain to try to revert PR rust-lang#76570. And we're going with the backup plan.

</details>

Original commit message follows:

----

 *Background*

In rust-lang#76570, new ABI strings including `C-unwind` were introduced. Their behavior is specified in RFC 2945 <sup>[1]</sup>.

However, it was reported in the #ffi-unwind stream of the Rust community Zulip that this had altered the way that `extern "C"` functions behaved even when the `c_unwind` feature gate was not active. <sup>[2]</sup>

 *Overview*

 This makes a small patch to `rustc_mir_build::build::should_abort_on_panic`, so that the same  behavior from before is in place when the `c_unwind` gate is not active.

`rustc_middle::ty::layout::fn_can_unwind` is not touched, as the visible behavior should not differ before/after rust-lang#76570. <sup>[3]</sup>

 ### Footnotes

 1.: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
 2.: https://rust-lang.zulipchat.com/#narrow/stream/210922-project-ffi-unwind/topic/Is.20unwinding.20through.20extern.20C.20UB.3F/near/230112325
 3.: https://github.com/rust-lang/rust/pull/76570/files#diff-b0320c2b8868f325d83c027fc5d71732636e9763551e35895488f30fe057c6e9L2599-R2617

 [1]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
 [2]: https://rust-lang.zulipchat.com/#narrow/stream/210922-project-ffi-unwind/topic/Is.20unwinding.20through.20extern.20C.20UB.3F/near/230112325
 [3]: https://github.com/rust-lang/rust/pull/76570/files#diff-b0320c2b8868f325d83c027fc5d71732636e9763551e35895488f30fe057c6e9L2599-R2617
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. 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.

9 participants