diff --git a/rust-version b/rust-version index 53ac7c54983..f064064db14 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -a4d9624242df6bfe6c0a298867dd2bd527263424 +b3ac52646f7591a811fa9bf55995b24fd17ece08 diff --git a/src/helpers.rs b/src/helpers.rs index 07356ab0203..e98488b9bf6 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -559,7 +559,7 @@ pub fn check_abi<'a>(abi: Abi, exp_abi: Abi) -> InterpResult<'a, ()> { if abi == exp_abi { Ok(()) } else { - throw_ub_format!("calling a function with ABI {:?} using caller ABI {:?}", exp_abi, abi) + throw_ub_format!("calling a function with ABI {} using caller ABI {}", exp_abi.name(), abi.name()) } } diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index 9203aafd576..373d5299618 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -146,14 +146,14 @@ fn emulate_foreign_item( | "exit" | "ExitProcess" => { - check_abi(abi, if link_name == "exit" { Abi::C } else { Abi::System })?; + check_abi(abi, if link_name == "exit" { Abi::C { unwind: false } } else { Abi::System { unwind: false } })?; let &[ref code] = check_arg_count(args)?; // it's really u32 for ExitProcess, but we have to put it into the `Exit` variant anyway let code = this.read_scalar(code)?.to_i32()?; throw_machine_stop!(TerminationInfo::Exit(code.into())); } "abort" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; throw_machine_stop!(TerminationInfo::Abort("the program aborted execution".to_owned())) } _ => throw_unsup_format!("can't call (diverging) foreign function: {}", link_name), @@ -170,7 +170,7 @@ fn emulate_foreign_item( // Normally, this will be either `libpanic_unwind` or `libpanic_abort`, but it could // also be a custom user-provided implementation via `#![feature(panic_runtime)]` "__rust_start_panic" | "__rust_panic_cleanup" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; // This replicates some of the logic in `inject_panic_runtime`. // FIXME: is there a way to reuse that logic? let panic_runtime = match this.tcx.sess.panic_strategy() { @@ -236,14 +236,14 @@ fn emulate_foreign_item_by_name( // Standard C allocation "malloc" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; let &[ref size] = check_arg_count(args)?; let size = this.read_scalar(size)?.to_machine_usize(this)?; let res = this.malloc(size, /*zero_init:*/ false, MiriMemoryKind::C); this.write_scalar(res, dest)?; } "calloc" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; let &[ref items, ref len] = check_arg_count(args)?; let items = this.read_scalar(items)?.to_machine_usize(this)?; let len = this.read_scalar(len)?.to_machine_usize(this)?; @@ -253,13 +253,13 @@ fn emulate_foreign_item_by_name( this.write_scalar(res, dest)?; } "free" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; let &[ref ptr] = check_arg_count(args)?; let ptr = this.read_scalar(ptr)?.check_init()?; this.free(ptr, MiriMemoryKind::C)?; } "realloc" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; let &[ref old_ptr, ref new_size] = check_arg_count(args)?; let old_ptr = this.read_scalar(old_ptr)?.check_init()?; let new_size = this.read_scalar(new_size)?.to_machine_usize(this)?; @@ -334,7 +334,7 @@ fn emulate_foreign_item_by_name( // C memory handling functions "memcmp" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; let &[ref left, ref right, ref n] = check_arg_count(args)?; let left = this.read_scalar(left)?.check_init()?; let right = this.read_scalar(right)?.check_init()?; @@ -355,7 +355,7 @@ fn emulate_foreign_item_by_name( this.write_scalar(Scalar::from_i32(result), dest)?; } "memrchr" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; let &[ref ptr, ref val, ref num] = check_arg_count(args)?; let ptr = this.read_scalar(ptr)?.check_init()?; let val = this.read_scalar(val)?.to_i32()? as u8; @@ -374,7 +374,7 @@ fn emulate_foreign_item_by_name( } } "memchr" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; let &[ref ptr, ref val, ref num] = check_arg_count(args)?; let ptr = this.read_scalar(ptr)?.check_init()?; let val = this.read_scalar(val)?.to_i32()? as u8; @@ -392,7 +392,7 @@ fn emulate_foreign_item_by_name( } } "strlen" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; let &[ref ptr] = check_arg_count(args)?; let ptr = this.read_scalar(ptr)?.check_init()?; let n = this.memory.read_c_str(ptr)?.len(); @@ -408,7 +408,7 @@ fn emulate_foreign_item_by_name( | "asinf" | "atanf" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; let &[ref f] = check_arg_count(args)?; // FIXME: Using host floats. let f = f32::from_bits(this.read_scalar(f)?.to_u32()?); @@ -428,7 +428,7 @@ fn emulate_foreign_item_by_name( | "hypotf" | "atan2f" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; let &[ref f1, ref f2] = check_arg_count(args)?; // underscore case for windows, here and below // (see https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/floating-point-primitives?view=vs-2019) @@ -450,7 +450,7 @@ fn emulate_foreign_item_by_name( | "asin" | "atan" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; let &[ref f] = check_arg_count(args)?; // FIXME: Using host floats. let f = f64::from_bits(this.read_scalar(f)?.to_u64()?); @@ -470,7 +470,7 @@ fn emulate_foreign_item_by_name( | "hypot" | "atan2" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; let &[ref f1, ref f2] = check_arg_count(args)?; // FIXME: Using host floats. let f1 = f64::from_bits(this.read_scalar(f1)?.to_u64()?); @@ -486,7 +486,7 @@ fn emulate_foreign_item_by_name( | "ldexp" | "scalbn" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; let &[ref x, ref exp] = check_arg_count(args)?; // For radix-2 (binary) systems, `ldexp` and `scalbn` are the same. let x = this.read_scalar(x)?.to_f64()?; @@ -508,12 +508,12 @@ fn emulate_foreign_item_by_name( // Architecture-specific shims "llvm.x86.sse2.pause" if this.tcx.sess.target.arch == "x86" || this.tcx.sess.target.arch == "x86_64" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; let &[] = check_arg_count(args)?; this.yield_active_thread(); } "llvm.aarch64.hint" if this.tcx.sess.target.arch == "aarch64" => { - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; let &[ref hint] = check_arg_count(args)?; let hint = this.read_scalar(hint)?.to_i32()?; match hint { diff --git a/src/shims/posix/dlsym.rs b/src/shims/posix/dlsym.rs index e1eccc68088..df9e945f29f 100644 --- a/src/shims/posix/dlsym.rs +++ b/src/shims/posix/dlsym.rs @@ -35,7 +35,7 @@ fn call_dlsym( ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; match dlsym { Dlsym::Linux(dlsym) => linux::EvalContextExt::call_dlsym(this, dlsym, args, ret), diff --git a/src/shims/posix/foreign_items.rs b/src/shims/posix/foreign_items.rs index 21b5ed62bbb..fdbe88cd7d6 100644 --- a/src/shims/posix/foreign_items.rs +++ b/src/shims/posix/foreign_items.rs @@ -22,7 +22,7 @@ fn emulate_foreign_item_by_name( ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); - check_abi(abi, Abi::C)?; + check_abi(abi, Abi::C { unwind: false })?; match link_name { // Environment related shims diff --git a/src/shims/windows/dlsym.rs b/src/shims/windows/dlsym.rs index 1f136060259..704b8872a4b 100644 --- a/src/shims/windows/dlsym.rs +++ b/src/shims/windows/dlsym.rs @@ -32,7 +32,7 @@ fn call_dlsym( let (_dest, _ret) = ret.expect("we don't support any diverging dlsym"); assert!(this.tcx.sess.target.os == "windows"); - check_abi(abi, Abi::System)?; + check_abi(abi, Abi::System { unwind: false })?; match dlsym {} } diff --git a/src/shims/windows/foreign_items.rs b/src/shims/windows/foreign_items.rs index f8d62f6b323..d9c5ce7896f 100644 --- a/src/shims/windows/foreign_items.rs +++ b/src/shims/windows/foreign_items.rs @@ -20,7 +20,7 @@ fn emulate_foreign_item_by_name( ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); - check_abi(abi, Abi::System)?; + check_abi(abi, Abi::System { unwind: false })?; // Windows API stubs. // HANDLE = isize diff --git a/tests/compile-fail/concurrency/unwind_top_of_stack.rs b/tests/compile-fail/concurrency/unwind_top_of_stack.rs index 93b15202fc3..c13a2ac8bb0 100644 --- a/tests/compile-fail/concurrency/unwind_top_of_stack.rs +++ b/tests/compile-fail/concurrency/unwind_top_of_stack.rs @@ -3,13 +3,13 @@ //! Unwinding past the top frame of a stack is Undefined Behavior. -#![feature(rustc_private)] +#![feature(rustc_private, c_unwind)] extern crate libc; use std::{mem, ptr}; -extern "C" fn thread_start(_null: *mut libc::c_void) -> *mut libc::c_void { +extern "C-unwind" fn thread_start(_null: *mut libc::c_void) -> *mut libc::c_void { panic!() } @@ -18,6 +18,9 @@ fn main() { let mut native: libc::pthread_t = mem::zeroed(); let attr: libc::pthread_attr_t = mem::zeroed(); // assert_eq!(libc::pthread_attr_init(&mut attr), 0); FIXME: this function is not yet implemented. + // Cast to avoid inserting abort-on-unwind. + let thread_start: extern "C-unwind" fn(*mut libc::c_void) -> *mut libc::c_void = thread_start; + let thread_start: extern "C" fn(*mut libc::c_void) -> *mut libc::c_void = mem::transmute(thread_start); assert_eq!(libc::pthread_create(&mut native, &attr, thread_start, ptr::null_mut()), 0); assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0); }