Skip to content

Commit ac3bca2

Browse files
committed
interpret: have assert_* intrinsics call the panic machinery instead of a direct abort
1 parent 788fd44 commit ac3bca2

File tree

16 files changed

+114
-43
lines changed

16 files changed

+114
-43
lines changed

compiler/rustc_const_eval/src/const_eval/error.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ pub enum ConstEvalErrKind {
1818
ModifiedGlobal,
1919
AssertFailure(AssertKind<ConstInt>),
2020
Panic { msg: Symbol, line: u32, col: u32, file: Symbol },
21-
Abort(String),
2221
}
2322

2423
impl MachineStopType for ConstEvalErrKind {
@@ -30,7 +29,6 @@ impl MachineStopType for ConstEvalErrKind {
3029
ModifiedGlobal => const_eval_modified_global,
3130
Panic { .. } => const_eval_panic,
3231
AssertFailure(x) => x.diagnostic_message(),
33-
Abort(msg) => msg.to_string().into(),
3432
}
3533
}
3634
fn add_args(
@@ -39,7 +37,7 @@ impl MachineStopType for ConstEvalErrKind {
3937
) {
4038
use ConstEvalErrKind::*;
4139
match *self {
42-
ConstAccessesStatic | ModifiedGlobal | Abort(_) => {}
40+
ConstAccessesStatic | ModifiedGlobal => {}
4341
AssertFailure(kind) => kind.add_args(adder),
4442
Panic { msg, line, col, file } => {
4543
adder("msg".into(), msg.into_diagnostic_arg());

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,13 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
464464
Ok(Some((ecx.load_mir(instance.def, None)?, orig_instance)))
465465
}
466466

467+
fn panic_nounwind(ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &str) -> InterpResult<'tcx> {
468+
let msg = Symbol::intern(msg);
469+
let span = ecx.find_closest_untracked_caller_location();
470+
let (file, line, col) = ecx.location_triple_for_span(span);
471+
return Err(ConstEvalErrKind::Panic { msg, file, line, col }.into());
472+
}
473+
467474
fn call_intrinsic(
468475
ecx: &mut InterpCx<'mir, 'tcx, Self>,
469476
instance: ty::Instance<'tcx>,
@@ -584,10 +591,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
584591
Err(ConstEvalErrKind::AssertFailure(err).into())
585592
}
586593

587-
fn abort(_ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: String) -> InterpResult<'tcx, !> {
588-
Err(ConstEvalErrKind::Abort(msg).into())
589-
}
590-
591594
fn binary_ptr_op(
592595
_ecx: &InterpCx<'mir, 'tcx, Self>,
593596
_bin_op: mir::BinOp,

compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
125125
) -> InterpResult<'tcx, bool> {
126126
let instance_args = instance.args;
127127
let intrinsic_name = self.tcx.item_name(instance.def_id());
128-
129-
// First handle intrinsics without return place.
130-
let ret = match ret {
131-
None => match intrinsic_name {
132-
sym::abort => M::abort(self, "the program aborted execution".to_owned())?,
133-
// Unsupported diverging intrinsic.
134-
_ => return Ok(false),
135-
},
136-
Some(p) => p,
128+
let Some(ret) = ret else {
129+
// We don't support any intrinsic without return place.
130+
return Ok(false);
137131
};
138132

139133
match intrinsic_name {
@@ -410,7 +404,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
410404
ValidityRequirement::Uninit => bug!("assert_uninit_valid doesn't exist"),
411405
};
412406

413-
M::abort(self, msg)?;
407+
M::panic_nounwind(self, &msg)?;
408+
// Skip the `go_to_block` at the end.
409+
return Ok(true);
414410
}
415411
}
416412
sym::simd_insert => {

compiler/rustc_const_eval/src/interpret/machine.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,8 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
218218
unwind: mir::UnwindAction,
219219
) -> InterpResult<'tcx>;
220220

221-
/// Called to abort evaluation.
222-
fn abort(_ecx: &mut InterpCx<'mir, 'tcx, Self>, _msg: String) -> InterpResult<'tcx, !> {
223-
throw_unsup_format!("aborting execution is not supported")
224-
}
221+
/// Called to trigger a non-unwinding panic.
222+
fn panic_nounwind(_ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &str) -> InterpResult<'tcx>;
225223

226224
/// Called when unwinding reached a state where execution should be terminated.
227225
fn unwind_terminate(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx>;

compiler/rustc_mir_transform/src/const_prop.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
180180
throw_machine_stop_str!("calling functions isn't supported in ConstProp")
181181
}
182182

183+
fn panic_nounwind(_ecx: &mut InterpCx<'mir, 'tcx, Self>, _msg: &str) -> InterpResult<'tcx> {
184+
throw_machine_stop_str!("panicking isn't supported in ConstProp")
185+
}
186+
183187
fn find_mir_or_eval_fn(
184188
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
185189
_instance: ty::Instance<'tcx>,

compiler/rustc_mir_transform/src/dataflow_const_prop.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,13 @@ impl<'mir, 'tcx: 'mir> rustc_const_eval::interpret::Machine<'mir, 'tcx> for Dumm
541541
unimplemented!()
542542
}
543543

544+
fn panic_nounwind(
545+
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
546+
_msg: &str,
547+
) -> interpret::InterpResult<'tcx> {
548+
unimplemented!()
549+
}
550+
544551
fn call_intrinsic(
545552
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
546553
_instance: ty::Instance<'tcx>,

src/tools/miri/src/machine.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -971,9 +971,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
971971
ecx.assert_panic(msg, unwind)
972972
}
973973

974-
#[inline(always)]
975-
fn abort(_ecx: &mut MiriInterpCx<'mir, 'tcx>, msg: String) -> InterpResult<'tcx, !> {
976-
throw_machine_stop!(TerminationInfo::Abort(msg))
974+
fn panic_nounwind(ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &str) -> InterpResult<'tcx> {
975+
ecx.start_panic_nounwind(msg)
977976
}
978977

979978
fn unwind_terminate(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {

src/tools/miri/src/shims/intrinsics/mod.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
3434
if this.emulate_intrinsic(instance, args, dest, ret)? {
3535
return Ok(());
3636
}
37-
38-
// All remaining supported intrinsics have a return place.
3937
let intrinsic_name = this.tcx.item_name(instance.def_id());
4038
let intrinsic_name = intrinsic_name.as_str();
39+
40+
// Handle intrinsics without return place.
41+
match intrinsic_name {
42+
"abort" => {
43+
throw_machine_stop!(TerminationInfo::Abort(
44+
"the program aborted execution".to_owned()
45+
))
46+
}
47+
_ => {},
48+
}
49+
50+
// All remaining supported intrinsics have a return place.
4151
let ret = match ret {
4252
None => throw_unsup_format!("unimplemented (diverging) intrinsic: `{intrinsic_name}`"),
4353
Some(p) => p,
@@ -393,7 +403,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
393403
"breakpoint" => {
394404
let [] = check_arg_count(args)?;
395405
// normally this would raise a SIGTRAP, which aborts if no debugger is connected
396-
throw_machine_stop!(TerminationInfo::Abort(format!("Trace/breakpoint trap")))
406+
throw_machine_stop!(TerminationInfo::Abort(format!("trace/breakpoint trap")))
397407
}
398408

399409
name => throw_unsup_format!("unimplemented intrinsic: `{name}`"),

src/tools/miri/src/shims/panic.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
188188
)
189189
}
190190

191+
/// Start a non-unwinding panic in the interpreter with the given message as payload.
192+
fn start_panic_nounwind(&mut self, msg: &str) -> InterpResult<'tcx> {
193+
let this = self.eval_context_mut();
194+
195+
// First arg: message.
196+
let msg = this.allocate_str(msg, MiriMemoryKind::Machine.into(), Mutability::Not)?;
197+
198+
// Call the lang item.
199+
let panic = this.tcx.lang_items().panic_nounwind().unwrap();
200+
let panic = ty::Instance::mono(this.tcx.tcx, panic);
201+
this.call_function(
202+
panic,
203+
Abi::Rust,
204+
&[msg.to_ref(this)],
205+
None,
206+
StackPopCleanup::Goto { ret: None, unwind: mir::UnwindAction::Unreachable },
207+
)
208+
}
209+
191210
fn assert_panic(
192211
&mut self,
193212
msg: &mir::AssertMessage<'tcx>,

src/tools/miri/tests/fail/breakpoint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
fn main() {
44
unsafe {
5-
core::intrinsics::breakpoint() //~ ERROR: Trace/breakpoint trap
5+
core::intrinsics::breakpoint() //~ ERROR: trace/breakpoint trap
66
};
77
}

src/tools/miri/tests/fail/breakpoint.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: abnormal termination: Trace/breakpoint trap
1+
error: abnormal termination: trace/breakpoint trap
22
--> $DIR/breakpoint.rs:LL:CC
33
|
44
LL | core::intrinsics::breakpoint()
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Trace/breakpoint trap
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trace/breakpoint trap
66
|
77
= note: inside `main` at $DIR/breakpoint.rs:LL:CC
88

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
//@normalize-stderr-test: "unsafe \{ libc::abort\(\) \}|crate::intrinsics::abort\(\);" -> "ABORT();"
2+
//@normalize-stderr-test: "\| +\^+" -> "| ^"
3+
//@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "$1"
4+
//@normalize-stderr-test: "\n at [^\n]+" -> "$1"
5+
//@error-in-other-file: aborted execution
16
#![feature(never_type)]
27

38
#[allow(deprecated, invalid_value)]
49
fn main() {
510
let _ = unsafe { std::mem::uninitialized::<!>() };
6-
//~^ ERROR: attempted to instantiate uninhabited type `!`
711
}

src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
1-
error: abnormal termination: aborted execution: attempted to instantiate uninhabited type `!`
1+
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
2+
aborted execution: attempted to instantiate uninhabited type `!`
3+
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
4+
thread caused non-unwinding panic. aborting.
5+
error: abnormal termination: the program aborted execution
6+
--> RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
7+
|
8+
LL | ABORT();
9+
| ^ the program aborted execution
10+
|
11+
= note: inside `std::sys::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
12+
= note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
13+
= note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
14+
= note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
15+
= note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
16+
= note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC
17+
note: inside `main`
218
--> $DIR/uninit_uninhabited_type.rs:LL:CC
319
|
420
LL | let _ = unsafe { std::mem::uninitialized::<!>() };
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!`
6-
|
7-
= note: inside `main` at $DIR/uninit_uninhabited_type.rs:LL:CC
21+
| ^
822

923
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1024

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
//@normalize-stderr-test: "unsafe \{ libc::abort\(\) \}|crate::intrinsics::abort\(\);" -> "ABORT();"
2+
//@normalize-stderr-test: "\| +\^+" -> "| ^"
3+
//@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "$1"
4+
//@normalize-stderr-test: "\n at [^\n]+" -> "$1"
5+
//@error-in-other-file: aborted execution
6+
17
#[allow(deprecated, invalid_value)]
28
fn main() {
39
let _ = unsafe { std::mem::zeroed::<fn()>() };
4-
//~^ ERROR: attempted to zero-initialize type `fn()`, which is invalid
510
}

src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
1-
error: abnormal termination: aborted execution: attempted to zero-initialize type `fn()`, which is invalid
1+
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
2+
aborted execution: attempted to zero-initialize type `fn()`, which is invalid
3+
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
4+
thread caused non-unwinding panic. aborting.
5+
error: abnormal termination: the program aborted execution
6+
--> RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
7+
|
8+
LL | ABORT();
9+
| ^ the program aborted execution
10+
|
11+
= note: inside `std::sys::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
12+
= note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
13+
= note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
14+
= note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
15+
= note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
16+
= note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC
17+
note: inside `main`
218
--> $DIR/zero_fn_ptr.rs:LL:CC
319
|
420
LL | let _ = unsafe { std::mem::zeroed::<fn()>() };
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `fn()`, which is invalid
6-
|
7-
= note: inside `main` at $DIR/zero_fn_ptr.rs:LL:CC
21+
| ^
822

923
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1024

tests/ui/consts/assert-type-intrinsics.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ error[E0080]: evaluation of constant value failed
22
--> $DIR/assert-type-intrinsics.rs:12:9
33
|
44
LL | MaybeUninit::<!>::uninit().assume_init();
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'aborted execution: attempted to instantiate uninhabited type `!`', $DIR/assert-type-intrinsics.rs:12:36
66

77
error[E0080]: evaluation of constant value failed
88
--> $DIR/assert-type-intrinsics.rs:16:9
99
|
1010
LL | intrinsics::assert_mem_uninitialized_valid::<&'static i32>();
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `&i32` uninitialized, which is invalid
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'aborted execution: attempted to leave type `&i32` uninitialized, which is invalid', $DIR/assert-type-intrinsics.rs:16:9
1212

1313
error[E0080]: evaluation of constant value failed
1414
--> $DIR/assert-type-intrinsics.rs:20:9
1515
|
1616
LL | intrinsics::assert_zero_valid::<&'static i32>();
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `&i32`, which is invalid
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'aborted execution: attempted to zero-initialize type `&i32`, which is invalid', $DIR/assert-type-intrinsics.rs:20:9
1818

1919
error: aborting due to 3 previous errors
2020

0 commit comments

Comments
 (0)