$(
$($($name:tt).*)|+ $(if $cond:expr)?, $(<$($subst:ident),*>)? ($($a:ident $arg:ident),*) $content:block;
)*) => {
+ let _ = $substs; // Silence warning when substs is unused.
match $intrinsic {
$(
$(intrinsic_pat!($($name).*))|* $(if $cond)? => {
"transmute" => {
trap_unreachable(
fx,
- "[corruption] Called intrinsic::transmute with uninhabited argument.",
+ "[corruption] Transmuting to uninhabited type.",
);
}
_ => unimplemented!("unsupported instrinsic {}", intrinsic),
intrinsic_match! {
fx, intrinsic, substs, args,
_ => {
- unimpl!("unsupported intrinsic {}", intrinsic)
+ unimpl_fatal!(fx.tcx, span, "unsupported intrinsic {}", intrinsic);
};
assume, (c _a) {};
let dst_layout = fx.layout_of(dst_ty);
ret.write_cvalue(fx, CValue::by_ref(addr, dst_layout))
};
- init, () {
- let layout = ret.layout();
- if layout.abi == Abi::Uninhabited {
- crate::trap::trap_panic(fx, "[panic] Called intrinsic::init for uninhabited type.");
- return;
- }
-
- match *ret.inner() {
- CPlaceInner::NoPlace => {}
- CPlaceInner::Var(var) => {
- let clif_ty = fx.clif_type(layout.ty).unwrap();
- let val = match clif_ty {
- types::I8 | types::I16 | types::I32 | types::I64 => fx.bcx.ins().iconst(clif_ty, 0),
- types::I128 => {
- let zero = fx.bcx.ins().iconst(types::I64, 0);
- fx.bcx.ins().iconcat(zero, zero)
- }
- types::F32 => {
- let zero = fx.bcx.ins().iconst(types::I32, 0);
- fx.bcx.ins().bitcast(types::F32, zero)
- }
- types::F64 => {
- let zero = fx.bcx.ins().iconst(types::I64, 0);
- fx.bcx.ins().bitcast(types::F64, zero)
- }
- _ => panic!("clif_type returned {}", clif_ty),
- };
- fx.bcx.set_val_label(val, cranelift_codegen::ir::ValueLabel::from_u32(var.as_u32()));
- fx.bcx.def_var(mir_var(var), val);
- }
- _ => {
- let addr = ret.to_ptr(fx).get_addr(fx);
- let layout = ret.layout();
- fx.bcx.emit_small_memset(fx.module.target_config(), addr, 0, layout.size.bytes(), 1);
- }
- }
- };
- uninit, () {
- let layout = ret.layout();
- if layout.abi == Abi::Uninhabited {
- crate::trap::trap_panic(fx, "[panic] Called intrinsic::uninit for uninhabited type.");
- return;
- }
- match *ret.inner() {
- CPlaceInner::NoPlace => {},
- CPlaceInner::Var(var) => {
- let clif_ty = fx.clif_type(layout.ty).unwrap();
- let val = match clif_ty {
- types::I8 | types::I16 | types::I32 | types::I64 => fx.bcx.ins().iconst(clif_ty, 42),
- types::I128 => {
- let zero = fx.bcx.ins().iconst(types::I64, 0);
- let fourty_two = fx.bcx.ins().iconst(types::I64, 42);
- fx.bcx.ins().iconcat(fourty_two, zero)
- }
- types::F32 => {
- let zero = fx.bcx.ins().iconst(types::I32, 0xdeadbeef);
- fx.bcx.ins().bitcast(types::F32, zero)
- }
- types::F64 => {
- let zero = fx.bcx.ins().iconst(types::I64, 0xcafebabedeadbeefu64 as i64);
- fx.bcx.ins().bitcast(types::F64, zero)
- }
- _ => panic!("clif_type returned {}", clif_ty),
- };
- fx.bcx.set_val_label(val, cranelift_codegen::ir::ValueLabel::from_u32(var.as_u32()));
- fx.bcx.def_var(mir_var(var), val);
- }
- CPlaceInner::Addr(_, _) => {
- // Don't write to `ret`, as the destination memory is already uninitialized.
- }
- }
- };
write_bytes, (c dst, v val, v count) {
let pointee_ty = dst.layout().ty.builtin_deref(true).unwrap().ty;
let pointee_size = fx.layout_of(pointee_ty).size.bytes();
let res = CValue::by_val(swap(&mut fx.bcx, arg), fx.layout_of(T));
ret.write_cvalue(fx, res);
};
- panic_if_uninhabited, <T> () {
- if fx.layout_of(T).abi.is_uninhabited() {
- crate::trap::trap_panic(fx, "[panic] Called intrinsic::panic_if_uninhabited for uninhabited type.");
+ assert_inhabited | assert_zero_valid | assert_uninit_valid, <T> () {
+ let layout = fx.layout_of(T);
+ if layout.abi.is_uninhabited() {
+ crate::trap::trap_panic(fx, &format!("attempted to instantiate uninhabited type `{}`", T));
+ return;
+ }
+
+ if intrinsic == "assert_zero_valid" && !layout.might_permit_raw_init(fx, /*zero:*/ true).unwrap() {
+ crate::trap::trap_panic(fx, &format!("attempted to zero-initialize type `{}`, which is invalid", T));
+ return;
+ }
+
+ if intrinsic == "assert_uninit_valid" && !layout.might_permit_raw_init(fx, /*zero:*/ false).unwrap() {
+ crate::trap::trap_panic(fx, &format!("attempted to leave type `{}` uninitialized, which is invalid", T));
return;
}
};
ret.write_cvalue(fx, val);
};
- try, (v f, v data, v _local_ptr) {
+ try, (v f, v data, v _catch_fn) {
// FIXME once unwinding is supported, change this to actually catch panics
let f_sig = fx.bcx.func.import_signature(Signature {
call_conv: CallConv::triple_default(fx.triple()),