File tree 4 files changed +46
-10
lines changed
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(
268
268
// optimize based on this!
269
269
false
270
270
} 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)]`.
272
273
true
273
274
} else if codegen_fn_attrs. flags . contains ( CodegenFnAttrFlags :: RUSTC_ALLOCATOR_NOUNWIND ) {
274
275
// Special attribute for allocator functions, which can't unwind
275
276
false
276
277
} else if let Some ( id) = id {
277
278
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
280
281
// unwind
281
282
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
287
283
} else {
288
284
// Anything else defined in Rust is assumed that it can possibly
289
285
// unwind
Original file line number Diff line number Diff line change 6
6
extern {
7
7
// CHECK: Function Attrs: nounwind
8
8
// 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
11
11
// CHECK: declare void @unwinding_extern_fn
12
12
#[ unwind( allowed) ]
13
13
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
14
32
}
15
33
16
34
pub unsafe fn force_declare ( ) {
17
35
extern_fn ( ) ;
18
36
unwinding_extern_fn ( ) ;
37
+ aborting_extern_fn ( ) ;
38
+ rust_extern_fn ( ) ;
39
+ rust_unwinding_extern_fn ( ) ;
40
+ rust_aborting_extern_fn ( ) ;
19
41
}
Original file line number Diff line number Diff line change 2
2
3
3
#![ crate_type = "lib" ]
4
4
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
+
5
8
// CHECK: Function Attrs: norecurse nounwind
6
9
pub 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