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");
}
}
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;
TerminatorKind::Assert {
cond,
expected,
- msg: _,
+ msg,
target,
cleanup: _,
} => {
} else {
fx.bcx.ins().brz(cond, target, &[]);
};
- trap_panic(&mut fx.bcx);
+ trap_panic(fx, format!("[panic] Assert {:?} failed.", msg));
}
TerminatorKind::SwitchInt {
} => {
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 { .. }
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 {
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.",
+ )
+ }
}
}
// 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),
}
};
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;
}
};
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;
}
};
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;
}
};
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.");
}
}
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);