Print message when reaching trap
This commit is contained in:
parent
970d164089
commit
c0ffc422ab
@ -590,7 +590,7 @@ pub fn codegen_terminator_call<'a, 'tcx: 'a>(
|
||||
let ret_ebb = fx.get_ebb(dest);
|
||||
fx.bcx.ins().jump(ret_ebb, &[]);
|
||||
} else {
|
||||
trap_unreachable(&mut fx.bcx);
|
||||
trap_unreachable(fx, "[corruption] Diverging function returned");
|
||||
}
|
||||
}
|
||||
|
||||
|
38
src/base.rs
38
src/base.rs
@ -108,9 +108,28 @@ fn trans_fn<'a, 'clif, 'tcx: 'a, B: Backend + 'static>(
|
||||
let start_ebb = bcx.create_ebb();
|
||||
bcx.append_ebb_params_for_function_params(start_ebb);
|
||||
bcx.switch_to_block(start_ebb);
|
||||
crate::trap::trap_unreachable(&mut bcx);
|
||||
bcx.seal_all_blocks();
|
||||
bcx.finalize();
|
||||
|
||||
let mut fx = FunctionCx {
|
||||
tcx,
|
||||
module: cx.module,
|
||||
pointer_type: pointer_ty(tcx),
|
||||
|
||||
instance,
|
||||
mir,
|
||||
|
||||
bcx,
|
||||
ebb_map: HashMap::new(),
|
||||
local_map: HashMap::new(),
|
||||
|
||||
clif_comments: crate::pretty_clif::CommentWriter::new(tcx, instance),
|
||||
constants: &mut cx.ccx,
|
||||
caches: &mut cx.caches,
|
||||
source_info_set: indexmap::IndexSet::new(),
|
||||
};
|
||||
|
||||
crate::trap::trap_unreachable(&mut fx, "[unimplemented] Called function with u128 or i128 as argument.");
|
||||
fx.bcx.seal_all_blocks();
|
||||
fx.bcx.finalize();
|
||||
|
||||
// Step 2b3. Define function
|
||||
cx.caches.context.func = func;
|
||||
@ -254,7 +273,7 @@ fn codegen_fn_content<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx, impl Backend>)
|
||||
TerminatorKind::Assert {
|
||||
cond,
|
||||
expected,
|
||||
msg: _,
|
||||
msg,
|
||||
target,
|
||||
cleanup: _,
|
||||
} => {
|
||||
@ -267,7 +286,7 @@ fn codegen_fn_content<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx, impl Backend>)
|
||||
} else {
|
||||
fx.bcx.ins().brz(cond, target, &[]);
|
||||
};
|
||||
trap_panic(&mut fx.bcx);
|
||||
trap_panic(fx, format!("[panic] Assert {:?} failed.", msg));
|
||||
}
|
||||
|
||||
TerminatorKind::SwitchInt {
|
||||
@ -294,8 +313,11 @@ fn codegen_fn_content<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx, impl Backend>)
|
||||
} => {
|
||||
crate::abi::codegen_terminator_call(fx, func, args, destination);
|
||||
}
|
||||
TerminatorKind::Resume | TerminatorKind::Abort | TerminatorKind::Unreachable => {
|
||||
trap_unreachable(&mut fx.bcx);
|
||||
TerminatorKind::Resume | TerminatorKind::Abort => {
|
||||
trap_unreachable(fx, "[corruption] Unwinding bb reached.");
|
||||
}
|
||||
TerminatorKind::Unreachable => {
|
||||
trap_unreachable(fx, "[corruption] Hit unreachable code.");
|
||||
}
|
||||
TerminatorKind::Yield { .. }
|
||||
| TerminatorKind::FalseEdges { .. }
|
||||
@ -742,7 +764,7 @@ pub fn trans_get_discriminant<'a, 'tcx: 'a>(
|
||||
let layout = place.layout();
|
||||
|
||||
if layout.abi == layout::Abi::Uninhabited {
|
||||
return trap_unreachable_ret_value(fx, dest_layout);
|
||||
return trap_unreachable_ret_value(fx, dest_layout, "[panic] Tried to get discriminant for uninhabited type.");
|
||||
}
|
||||
|
||||
let (discr_scalar, discr_kind) = match &layout.variants {
|
||||
|
@ -69,7 +69,13 @@ pub fn trans_promoted<'a, 'tcx: 'a>(
|
||||
debug_assert_eq!(cplace.layout(), fx.layout_of(dest_ty));
|
||||
cplace
|
||||
}
|
||||
Err(_) => crate::trap::trap_unreachable_ret_place(fx, fx.layout_of(dest_ty)),
|
||||
Err(_) => {
|
||||
crate::trap::trap_unreachable_ret_place(
|
||||
fx,
|
||||
fx.layout_of(dest_ty),
|
||||
"[panic] Tried to get value of promoted value with errored during const eval.",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,10 +103,10 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
|
||||
// Insert non returning intrinsics here
|
||||
match intrinsic {
|
||||
"abort" => {
|
||||
trap_panic(&mut fx.bcx);
|
||||
trap_panic(fx, "Called intrinisc::abort.");
|
||||
}
|
||||
"unreachable" => {
|
||||
trap_unreachable(&mut fx.bcx);
|
||||
trap_unreachable(fx, "[corruption] Called intrinsic::unreachable.");
|
||||
}
|
||||
_ => unimplemented!("unsupported instrinsic {}", intrinsic),
|
||||
}
|
||||
@ -339,7 +339,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
|
||||
};
|
||||
init, () {
|
||||
if ret.layout().abi == Abi::Uninhabited {
|
||||
crate::trap::trap_panic(&mut fx.bcx);
|
||||
crate::trap::trap_panic(fx, "[panic] Called intrinsic::init for uninhabited type.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -377,7 +377,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
|
||||
};
|
||||
uninit, <T> () {
|
||||
if ret.layout().abi == Abi::Uninhabited {
|
||||
crate::trap::trap_panic(&mut fx.bcx);
|
||||
crate::trap::trap_panic(fx, "[panic] Called intrinsic::uninit for uninhabited type.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -412,7 +412,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
|
||||
};
|
||||
panic_if_uninhabited, <T> () {
|
||||
if fx.layout_of(T).abi.is_uninhabited() {
|
||||
crate::trap::trap_panic(&mut fx.bcx);
|
||||
crate::trap::trap_panic(fx, "[panic] Called intrinsic::panic_if_uninhabited for uninhabited type.");
|
||||
return;
|
||||
}
|
||||
};
|
||||
@ -492,6 +492,6 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
|
||||
let ret_ebb = fx.get_ebb(dest);
|
||||
fx.bcx.ins().jump(ret_ebb, &[]);
|
||||
} else {
|
||||
trap_unreachable(&mut fx.bcx);
|
||||
trap_unreachable(fx, "[corruption] Diverging intrinsic returned.");
|
||||
}
|
||||
}
|
||||
|
40
src/trap.rs
40
src/trap.rs
@ -1,23 +1,51 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
fn codegen_print(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, msg: &str) {
|
||||
let puts = fx.module.declare_function("puts", Linkage::Import, &Signature {
|
||||
call_conv: CallConv::SystemV,
|
||||
params: vec![AbiParam::new(pointer_ty(fx.tcx))],
|
||||
returns: vec![],
|
||||
}).unwrap();
|
||||
let puts = fx.module.declare_func_in_func(puts, &mut fx.bcx.func);
|
||||
|
||||
let symbol_name = fx.tcx.symbol_name(fx.instance);
|
||||
let msg_bytes = format!("trap at {:?} ({}): {}\0", fx.instance, symbol_name, msg).into_bytes().into_boxed_slice();
|
||||
let mut data_ctx = DataContext::new();
|
||||
data_ctx.define(msg_bytes);
|
||||
let msg_id = fx.module.declare_data(&(symbol_name.as_str().to_string() + msg), Linkage::Local, false).unwrap();
|
||||
|
||||
// Ignore DuplicateDefinition error, as the data will be the same
|
||||
let _ = fx.module.define_data(msg_id, &data_ctx);
|
||||
|
||||
let local_msg_id = fx.module.declare_data_in_func(msg_id, fx.bcx.func);
|
||||
let msg_ptr = fx.bcx.ins().global_value(pointer_ty(fx.tcx), local_msg_id);
|
||||
fx.bcx.ins().call(puts, &[msg_ptr]);
|
||||
}
|
||||
|
||||
/// Trap code: user0
|
||||
pub fn trap_panic(bcx: &mut FunctionBuilder) {
|
||||
bcx.ins().trap(TrapCode::User(0));
|
||||
pub fn trap_panic(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, msg: impl AsRef<str>) {
|
||||
codegen_print(fx, msg.as_ref());
|
||||
fx.bcx.ins().trap(TrapCode::User(0));
|
||||
}
|
||||
|
||||
/// Trap code: user65535
|
||||
pub fn trap_unreachable(bcx: &mut FunctionBuilder) {
|
||||
bcx.ins().trap(TrapCode::User(!0));
|
||||
pub fn trap_unreachable(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, msg: impl AsRef<str>) {
|
||||
codegen_print(fx, msg.as_ref());
|
||||
fx.bcx.ins().trap(TrapCode::User(!0));
|
||||
}
|
||||
|
||||
pub fn trap_unreachable_ret_value<'tcx>(fx: &mut FunctionCx<'_, 'tcx, impl cranelift_module::Backend>, dest_layout: TyLayout<'tcx>) -> CValue<'tcx> {
|
||||
/// Trap code: user65535
|
||||
pub fn trap_unreachable_ret_value<'tcx>(fx: &mut FunctionCx<'_, 'tcx, impl cranelift_module::Backend>, dest_layout: TyLayout<'tcx>, msg: impl AsRef<str>) -> CValue<'tcx> {
|
||||
codegen_print(fx, msg.as_ref());
|
||||
let true_ = fx.bcx.ins().iconst(types::I32, 1);
|
||||
fx.bcx.ins().trapnz(true_, TrapCode::User(!0));
|
||||
let zero = fx.bcx.ins().iconst(fx.pointer_type, 0);
|
||||
CValue::ByRef(zero, dest_layout)
|
||||
}
|
||||
|
||||
pub fn trap_unreachable_ret_place<'tcx>(fx: &mut FunctionCx<'_, 'tcx, impl cranelift_module::Backend>, dest_layout: TyLayout<'tcx>) -> CPlace<'tcx> {
|
||||
/// Trap code: user65535
|
||||
pub fn trap_unreachable_ret_place<'tcx>(fx: &mut FunctionCx<'_, 'tcx, impl cranelift_module::Backend>, dest_layout: TyLayout<'tcx>, msg: impl AsRef<str>) -> CPlace<'tcx> {
|
||||
codegen_print(fx, msg.as_ref());
|
||||
let true_ = fx.bcx.ins().iconst(types::I32, 1);
|
||||
fx.bcx.ins().trapnz(true_, TrapCode::User(!0));
|
||||
let zero = fx.bcx.ins().iconst(fx.pointer_type, 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user