File tree Expand file tree Collapse file tree 4 files changed +46
-10
lines changed Expand file tree Collapse file tree 4 files changed +46
-10
lines changed Original file line number Diff line number Diff line change @@ -268,22 +268,18 @@ pub fn from_fn_attrs(
268268 // optimize based on this!
269269 false
270270 } else if codegen_fn_attrs. flags . contains ( CodegenFnAttrFlags :: UNWIND ) {
271- // If a specific #[unwind] attribute is present, use that
271+ // If a specific #[unwind] attribute is present, use that.
272+ // FIXME: We currently assume it can unwind even with `#[unwind(aborts)]`.
272273 true
273274 } else if codegen_fn_attrs. flags . contains ( CodegenFnAttrFlags :: RUSTC_ALLOCATOR_NOUNWIND ) {
274275 // Special attribute for allocator functions, which can't unwind
275276 false
276277 } else if let Some ( id) = id {
277278 let sig = cx. tcx . normalize_erasing_late_bound_regions ( ty:: ParamEnv :: reveal_all ( ) , & sig) ;
278- if cx. tcx . is_foreign_item ( id) {
279- // Foreign items like `extern "C" { fn foo(); }` are assumed not to
279+ if cx. tcx . is_foreign_item ( id) && sig . abi != Abi :: Rust && sig . abi != Abi :: RustCall {
280+ // Foreign non-Rust items like `extern "C" { fn foo(); }` are assumed not to
280281 // unwind
281282 false
282- } else if sig. abi != Abi :: Rust && sig. abi != Abi :: RustCall {
283- // Any items defined in Rust that *don't* have the `extern` ABI are
284- // defined to not unwind. We insert shims to abort if an unwind
285- // happens to enforce this.
286- false
287283 } else {
288284 // Anything else defined in Rust is assumed that it can possibly
289285 // unwind
Original file line number Diff line number Diff line change 66extern {
77// CHECK: Function Attrs: nounwind
88// CHECK-NEXT: declare void @extern_fn
9- fn extern_fn ( ) ;
10- // CHECK-NOT: Function Attrs: nounwind
9+ fn extern_fn ( ) ; // assumed not to unwind
10+ // CHECK-NOT: nounwind
1111// CHECK: declare void @unwinding_extern_fn
1212 #[ unwind( allowed) ]
1313 fn unwinding_extern_fn ( ) ;
14+ // CHECK-NOT: nounwind
15+ // CHECK: declare void @aborting_extern_fn
16+ #[ unwind( aborts) ]
17+ fn aborting_extern_fn ( ) ; // FIXME: we don't have the attribute here
18+ }
19+
20+ extern "Rust" {
21+ // CHECK-NOT: nounwind
22+ // CHECK: declare void @rust_extern_fn
23+ fn rust_extern_fn ( ) ;
24+ // CHECK-NOT: nounwind
25+ // CHECK: declare void @rust_unwinding_extern_fn
26+ #[ unwind( allowed) ]
27+ fn rust_unwinding_extern_fn ( ) ;
28+ // CHECK-NOT: nounwind
29+ // CHECK: declare void @rust_aborting_extern_fn
30+ #[ unwind( aborts) ]
31+ fn rust_aborting_extern_fn ( ) ; // FIXME: we don't have the attribute here
1432}
1533
1634pub unsafe fn force_declare ( ) {
1735 extern_fn ( ) ;
1836 unwinding_extern_fn ( ) ;
37+ aborting_extern_fn ( ) ;
38+ rust_extern_fn ( ) ;
39+ rust_unwinding_extern_fn ( ) ;
40+ rust_aborting_extern_fn ( ) ;
1941}
Original file line number Diff line number Diff line change 22
33#![ crate_type = "lib" ]
44
5+ // The `nounwind` attribute does not get added by rustc; it is present here because LLVM
6+ // analyses determine that this function does not unwind.
7+
58// CHECK: Function Attrs: norecurse nounwind
69pub extern fn foo ( ) { }
Original file line number Diff line number Diff line change 1+ // compile-flags: -C opt-level=0
2+
3+ #![ crate_type = "lib" ]
4+ #![ feature( unwind_attributes) ]
5+
6+ // make sure these all do *not* get the attribute
7+ // CHECK-NOT: nounwind
8+
9+ pub extern fn foo ( ) { } // right now we don't abort-on-panic, so we also shouldn't have `nounwind`
10+ #[ unwind( allowed) ]
11+ pub extern fn foo_allowed ( ) { }
12+
13+ pub extern "Rust" fn bar ( ) { }
14+ #[ unwind( allowed) ]
15+ pub extern "Rust" fn bar_allowed ( ) { }
You can’t perform that action at this time.
0 commit comments