Rollup merge of #110233 - nbdd0121:intrinsic, r=tmiasko
Make rust-intrinsic ABI unwindable Fix #104451, fix https://github.com/rust-lang/miri/issues/2839 r? `@RalfJung`
This commit is contained in:
commit
e85ecbbcdc
14 changed files with 289 additions and 13 deletions
|
|
@ -1226,10 +1226,11 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: SpecAbi) ->
|
|||
| AvrNonBlockingInterrupt
|
||||
| CCmseNonSecureCall
|
||||
| Wasm
|
||||
| RustIntrinsic
|
||||
| PlatformIntrinsic
|
||||
| Unadjusted => false,
|
||||
Rust | RustCall | RustCold => tcx.sess.panic_strategy() == PanicStrategy::Unwind,
|
||||
Rust | RustCall | RustCold | RustIntrinsic => {
|
||||
tcx.sess.panic_strategy() == PanicStrategy::Unwind
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -615,12 +615,15 @@ impl<'f> Drop for VaListImpl<'f> {
|
|||
extern "rust-intrinsic" {
|
||||
/// Destroy the arglist `ap` after initialization with `va_start` or
|
||||
/// `va_copy`.
|
||||
#[rustc_nounwind]
|
||||
fn va_end(ap: &mut VaListImpl<'_>);
|
||||
|
||||
/// Copies the current location of arglist `src` to the arglist `dst`.
|
||||
#[rustc_nounwind]
|
||||
fn va_copy<'f>(dest: *mut VaListImpl<'f>, src: &VaListImpl<'f>);
|
||||
|
||||
/// Loads an argument of type `T` from the `va_list` `ap` and increment the
|
||||
/// argument `ap` points to.
|
||||
#[rustc_nounwind]
|
||||
fn va_arg<T: sealed_trait::VaArgSafe>(ap: &mut VaListImpl<'_>) -> T;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1371,6 +1371,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
|
|||
// as `intrinsics::copy_nonoverlapping` is a wrapper function.
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
|
||||
#[rustc_nounwind]
|
||||
fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -498,6 +498,7 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
|
|||
// This function cannot be marked as `unsafe` because `intrinsics::r#try`
|
||||
// expects normal function pointers.
|
||||
#[inline]
|
||||
#[rustc_nounwind] // `intrinsic::r#try` requires catch fn to be nounwind
|
||||
fn do_catch<F: FnOnce() -> R, R>(data: *mut u8, payload: *mut u8) {
|
||||
// SAFETY: this is the responsibility of the caller, see above.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
// MIR for `main` after AbortUnwindingCalls
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/issue_104451_unwindable_intrinsics.rs:+0:11: +0:11
|
||||
let mut _1: !; // in scope 0 at $DIR/issue_104451_unwindable_intrinsics.rs:+2:9: +2:62
|
||||
let mut _2: (); // in scope 0 at $DIR/issue_104451_unwindable_intrinsics.rs:+2:45: +2:47
|
||||
scope 1 {
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1); // scope 1 at $DIR/issue_104451_unwindable_intrinsics.rs:+2:9: +2:62
|
||||
StorageLive(_2); // scope 1 at $DIR/issue_104451_unwindable_intrinsics.rs:+2:45: +2:47
|
||||
_2 = (); // scope 1 at $DIR/issue_104451_unwindable_intrinsics.rs:+2:45: +2:47
|
||||
_1 = const_eval_select::<(), fn() -> ! {ow_ct}, fn() -> ! {ow_ct}, !>(move _2, ow_ct, ow_ct); // scope 1 at $DIR/issue_104451_unwindable_intrinsics.rs:+2:9: +2:62
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue_104451_unwindable_intrinsics.rs:8:9: 8:44
|
||||
// + literal: Const { ty: unsafe extern "rust-intrinsic" fn((), fn() -> ! {ow_ct}, fn() -> ! {ow_ct}) -> ! {const_eval_select::<(), fn() -> ! {ow_ct}, fn() -> ! {ow_ct}, !>}, val: Value(<ZST>) }
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue_104451_unwindable_intrinsics.rs:8:49: 8:54
|
||||
// + literal: Const { ty: fn() -> ! {ow_ct}, val: Value(<ZST>) }
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue_104451_unwindable_intrinsics.rs:8:56: 8:61
|
||||
// + literal: Const { ty: fn() -> ! {ow_ct}, val: Value(<ZST>) }
|
||||
}
|
||||
}
|
||||
14
tests/mir-opt/issue_104451_unwindable_intrinsics.rs
Normal file
14
tests/mir-opt/issue_104451_unwindable_intrinsics.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Check that `UnwindAction::Unreachable` is not generated for unwindable intrinsics.
|
||||
// ignore-wasm32 compiled with panic=abort by default
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
// EMIT_MIR issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.mir
|
||||
fn main() {
|
||||
unsafe {
|
||||
core::intrinsics::const_eval_select((), ow_ct, ow_ct)
|
||||
}
|
||||
}
|
||||
|
||||
const fn ow_ct() -> ! {
|
||||
panic!();
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
StorageLive(_1); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38
|
||||
- _1 = std::intrinsics::assume(const true) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38
|
||||
- // mir::Constant
|
||||
- // + span: $DIR/lower_intrinsics.rs:105:9: 105:32
|
||||
- // + span: $DIR/lower_intrinsics.rs:106:9: 106:32
|
||||
- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(bool) {std::intrinsics::assume}, val: Value(<ZST>) }
|
||||
+ assume(const true); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38
|
||||
+ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
StorageDead(_9); // scope 3 at $DIR/lower_intrinsics.rs:+4:90: +4:91
|
||||
- _3 = copy_nonoverlapping::<i32>(move _4, move _8, const 0_usize) -> [return: bb1, unwind unreachable]; // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95
|
||||
- // mir::Constant
|
||||
- // + span: $DIR/lower_intrinsics.rs:98:9: 98:28
|
||||
- // + span: $DIR/lower_intrinsics.rs:99:9: 99:28
|
||||
- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const i32, *mut i32, usize) {copy_nonoverlapping::<i32>}, val: Value(<ZST>) }
|
||||
+ copy_nonoverlapping(dst = move _8, src = move _4, count = const 0_usize); // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95
|
||||
+ goto -> bb1; // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
_4 = &raw const (*_1); // scope 1 at $DIR/lower_intrinsics.rs:+2:55: +2:56
|
||||
- _3 = option_payload_ptr::<usize>(move _4) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:18: +2:57
|
||||
- // mir::Constant
|
||||
- // + span: $DIR/lower_intrinsics.rs:132:18: 132:54
|
||||
- // + span: $DIR/lower_intrinsics.rs:133:18: 133:54
|
||||
- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const Option<usize>) -> *const usize {option_payload_ptr::<usize>}, val: Value(<ZST>) }
|
||||
+ _3 = &raw const (((*_4) as Some).0: usize); // scope 1 at $DIR/lower_intrinsics.rs:+2:18: +2:57
|
||||
+ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+2:18: +2:57
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
_6 = &raw const (*_2); // scope 2 at $DIR/lower_intrinsics.rs:+3:55: +3:56
|
||||
- _5 = option_payload_ptr::<String>(move _6) -> [return: bb2, unwind unreachable]; // scope 2 at $DIR/lower_intrinsics.rs:+3:18: +3:57
|
||||
- // mir::Constant
|
||||
- // + span: $DIR/lower_intrinsics.rs:133:18: 133:54
|
||||
- // + span: $DIR/lower_intrinsics.rs:134:18: 134:54
|
||||
- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const Option<String>) -> *const String {option_payload_ptr::<String>}, val: Value(<ZST>) }
|
||||
+ _5 = &raw const (((*_6) as Some).0: std::string::String); // scope 2 at $DIR/lower_intrinsics.rs:+3:18: +3:57
|
||||
+ goto -> bb2; // scope 2 at $DIR/lower_intrinsics.rs:+3:18: +3:57
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
_2 = &raw const (*_1); // scope 1 at $DIR/lower_intrinsics.rs:+1:46: +1:47
|
||||
- _0 = read_via_copy::<i32>(move _2) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48
|
||||
- // mir::Constant
|
||||
- // + span: $DIR/lower_intrinsics.rs:118:14: 118:45
|
||||
- // + span: $DIR/lower_intrinsics.rs:119:14: 119:45
|
||||
- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const i32) -> i32 {read_via_copy::<i32>}, val: Value(<ZST>) }
|
||||
+ _0 = (*_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48
|
||||
+ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
_2 = &raw const (*_1); // scope 1 at $DIR/lower_intrinsics.rs:+1:46: +1:47
|
||||
- _0 = read_via_copy::<Never>(move _2) -> unwind unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48
|
||||
- // mir::Constant
|
||||
- // + span: $DIR/lower_intrinsics.rs:123:14: 123:45
|
||||
- // + span: $DIR/lower_intrinsics.rs:124:14: 124:45
|
||||
- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const Never) -> Never {read_via_copy::<Never>}, val: Value(<ZST>) }
|
||||
+ unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// unit-test: LowerIntrinsics
|
||||
// ignore-wasm32 compiled with panic=abort by default
|
||||
|
||||
#![feature(core_intrinsics, intrinsics)]
|
||||
#![feature(core_intrinsics, intrinsics, rustc_attrs)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// EMIT_MIR lower_intrinsics.wrapping.LowerIntrinsics.diff
|
||||
|
|
@ -87,6 +87,7 @@ pub fn discriminant<T>(t: T) {
|
|||
|
||||
extern "rust-intrinsic" {
|
||||
// Cannot use `std::intrinsics::copy_nonoverlapping` as that is a wrapper function
|
||||
#[rustc_nounwind]
|
||||
fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
_5 = _2; // scope 0 at $DIR/lower_intrinsics.rs:+1:53: +1:54
|
||||
- _3 = add_with_overflow::<i32>(move _4, move _5) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:55
|
||||
- // mir::Constant
|
||||
- // + span: $DIR/lower_intrinsics.rs:111:14: 111:49
|
||||
- // + span: $DIR/lower_intrinsics.rs:112:14: 112:49
|
||||
- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> (i32, bool) {add_with_overflow::<i32>}, val: Value(<ZST>) }
|
||||
+ _3 = CheckedAdd(move _4, move _5); // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:55
|
||||
+ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:55
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
_8 = _2; // scope 1 at $DIR/lower_intrinsics.rs:+2:53: +2:54
|
||||
- _6 = sub_with_overflow::<i32>(move _7, move _8) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:55
|
||||
- // mir::Constant
|
||||
- // + span: $DIR/lower_intrinsics.rs:112:14: 112:49
|
||||
- // + span: $DIR/lower_intrinsics.rs:113:14: 113:49
|
||||
- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> (i32, bool) {sub_with_overflow::<i32>}, val: Value(<ZST>) }
|
||||
+ _6 = CheckedSub(move _7, move _8); // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:55
|
||||
+ goto -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:55
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
_11 = _2; // scope 2 at $DIR/lower_intrinsics.rs:+3:53: +3:54
|
||||
- _9 = mul_with_overflow::<i32>(move _10, move _11) -> [return: bb3, unwind unreachable]; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:55
|
||||
- // mir::Constant
|
||||
- // + span: $DIR/lower_intrinsics.rs:113:14: 113:49
|
||||
- // + span: $DIR/lower_intrinsics.rs:114:14: 114:49
|
||||
- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> (i32, bool) {mul_with_overflow::<i32>}, val: Value(<ZST>) }
|
||||
+ _9 = CheckedMul(move _10, move _11); // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:55
|
||||
+ goto -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:55
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue