Skip to content

Abort instead of panic on asserting intrinsics #1239

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

Merged
merged 3 commits into from
Mar 18, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,8 @@ pub fn report_diagnostic<'tcx, 'mir>(
let info = info.downcast_ref::<TerminationInfo>().expect("invalid MachineStop payload");
match info {
TerminationInfo::Exit(code) => return Some(*code),
TerminationInfo::Abort => format!("the evaluated program aborted execution"),
TerminationInfo::Abort(None) => format!("the evaluated program aborted execution"),
TerminationInfo::Abort(Some(msg)) => format!("the evaluated program aborted execution: {}", msg),
}
}
err_unsup!(NoMirFor(..)) => format!(
2 changes: 1 addition & 1 deletion src/eval.rs
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ impl Default for MiriConfig {
/// Details of premature program termination.
pub enum TerminationInfo {
Exit(i64),
Abort,
Abort(Option<String>),
}

/// Returns a freshly created `InterpCx`, along with an `MPlaceTy` representing
2 changes: 1 addition & 1 deletion src/machine.rs
Original file line number Diff line number Diff line change
@@ -273,7 +273,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {

#[inline(always)]
fn abort(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx, !> {
throw_machine_stop!(TerminationInfo::Abort)
throw_machine_stop!(TerminationInfo::Abort(None))
}

#[inline(always)]
8 changes: 4 additions & 4 deletions src/shims/intrinsics.rs
Original file line number Diff line number Diff line change
@@ -440,15 +440,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
"assert_uninit_valid" => {
let ty = substs.type_at(0);
let layout = this.layout_of(ty)?;
// Return here because we panicked instead of returning normally from the intrinsic.
// Abort here because the caller might not be panic safe.
if layout.abi.is_uninhabited() {
return this.start_panic(&format!("attempted to instantiate uninhabited type `{}`", ty), unwind);
throw_machine_stop!(TerminationInfo::Abort(Some(format!("attempted to instantiate uninhabited type `{}`", ty))))
}
if intrinsic_name == "assert_zero_valid" && !layout.might_permit_raw_init(this, /*zero:*/ true).unwrap() {
return this.start_panic(&format!("attempted to zero-initialize type `{}`, which is invalid", ty), unwind);
throw_machine_stop!(TerminationInfo::Abort(Some(format!("attempted to zero-initialize type `{}`, which is invalid", ty))))
}
if intrinsic_name == "assert_uninit_valid" && !layout.might_permit_raw_init(this, /*zero:*/ false).unwrap() {
return this.start_panic(&format!("attempted to leave type `{}` uninitialized, which is invalid", ty), unwind);
throw_machine_stop!(TerminationInfo::Abort(Some(format!("attempted to leave type `{}` uninitialized, which is invalid", ty))))
}
}

6 changes: 6 additions & 0 deletions tests/compile-fail/invalid_zero_init.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// error-pattern: the evaluated program aborted execution: attempted to zero-initialize type `fn()`, which is invalid

#[allow(deprecated, invalid_value)]
fn main() {
unsafe { std::mem::zeroed::<fn()>() };
}
7 changes: 7 additions & 0 deletions tests/compile-fail/uninit_uninhabited_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// error-pattern: the evaluated program aborted execution: attempted to instantiate uninhabited type `!`
#![feature(never_type)]

#[allow(deprecated, invalid_value)]
fn main() {
unsafe { std::mem::uninitialized::<!>() };
}
37 changes: 0 additions & 37 deletions tests/run-pass/panic/catch_panic.rs
Original file line number Diff line number Diff line change
@@ -67,43 +67,6 @@ fn main() {
|_old_val| { let _val = 1/0; loop {} },
);

// libcore panics from shims.
#[allow(deprecated, invalid_value)]
{
test(
Some("attempted to instantiate uninhabited type `!`"),
|_old_val| unsafe { std::mem::uninitialized::<!>() },
);
test(
Some("attempted to instantiate uninhabited type `!`"),
|_old_val| unsafe { std::mem::zeroed::<!>() },
);
test(
Some("attempted to leave type `fn()` uninitialized, which is invalid"),
|_old_val| unsafe { std::mem::uninitialized::<fn()>(); loop {} },
);
test(
Some("attempted to zero-initialize type `fn()`, which is invalid"),
|_old_val| unsafe { std::mem::zeroed::<fn()>(); loop {} },
);
test(
Some("attempted to leave type `*const dyn std::marker::Sync` uninitialized, which is invalid"),
|_old_val| unsafe { std::mem::uninitialized::<*const dyn Sync>(); loop {} },
);
test(
Some("attempted to zero-initialize type `*mut dyn std::marker::Sync`, which is invalid"),
|_old_val| unsafe { std::mem::zeroed::<*mut dyn Sync>(); loop {} },
);
test(
Some("attempted to leave type `&u8` uninitialized, which is invalid"),
|_old_val| unsafe { std::mem::uninitialized::<&u8>(); loop {} },
);
test(
Some("attempted to zero-initialize type `&u8`, which is invalid"),
|_old_val| unsafe { std::mem::zeroed::<&u8>(); loop {} },
);
}

test(
Some("align_offset: align is not a power-of-two"),
|_old_val| { (0usize as *const u8).align_offset(3); loop {} },
20 changes: 2 additions & 18 deletions tests/run-pass/panic/catch_panic.stderr
Original file line number Diff line number Diff line change
@@ -16,27 +16,11 @@ thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 4'
Caught panic message (String): index out of bounds: the len is 3 but the index is 4
thread 'main' panicked at 'attempt to divide by zero', $DIR/catch_panic.rs:67:33
Caught panic message (String): attempt to divide by zero
thread 'main' panicked at 'attempted to instantiate uninhabited type `!`', $LOC
Caught panic message (String): attempted to instantiate uninhabited type `!`
thread 'main' panicked at 'attempted to instantiate uninhabited type `!`', $LOC
Caught panic message (String): attempted to instantiate uninhabited type `!`
thread 'main' panicked at 'attempted to leave type `fn()` uninitialized, which is invalid', $LOC
Caught panic message (String): attempted to leave type `fn()` uninitialized, which is invalid
thread 'main' panicked at 'attempted to zero-initialize type `fn()`, which is invalid', $LOC
Caught panic message (String): attempted to zero-initialize type `fn()`, which is invalid
thread 'main' panicked at 'attempted to leave type `*const dyn std::marker::Sync` uninitialized, which is invalid', $LOC
Caught panic message (String): attempted to leave type `*const dyn std::marker::Sync` uninitialized, which is invalid
thread 'main' panicked at 'attempted to zero-initialize type `*mut dyn std::marker::Sync`, which is invalid', $LOC
Caught panic message (String): attempted to zero-initialize type `*mut dyn std::marker::Sync`, which is invalid
thread 'main' panicked at 'attempted to leave type `&u8` uninitialized, which is invalid', $LOC
Caught panic message (String): attempted to leave type `&u8` uninitialized, which is invalid
thread 'main' panicked at 'attempted to zero-initialize type `&u8`, which is invalid', $LOC
Caught panic message (String): attempted to zero-initialize type `&u8`, which is invalid
thread 'main' panicked at 'align_offset: align is not a power-of-two', $LOC
Caught panic message (String): align_offset: align is not a power-of-two
thread 'main' panicked at 'assertion failed: false', $DIR/catch_panic.rs:113:29
thread 'main' panicked at 'assertion failed: false', $DIR/catch_panic.rs:76:29
Caught panic message (&str): assertion failed: false
thread 'main' panicked at 'assertion failed: false', $DIR/catch_panic.rs:114:29
thread 'main' panicked at 'assertion failed: false', $DIR/catch_panic.rs:77:29
Caught panic message (&str): assertion failed: false
thread 'main' panicked at 'attempt to copy from unaligned or null pointer', $LOC
Caught panic message (String): attempt to copy from unaligned or null pointer