use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::subst::SubstsRef;
use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_target::abi::InitKind;
use crate::prelude::*;
use cranelift_codegen::ir::AtomicRmwOp;
fx: &mut FunctionCx<'_, '_, 'tcx>,
instance: Instance<'tcx>,
args: &[mir::Operand<'tcx>],
- destination: Option<(CPlace<'tcx>, BasicBlock)>,
- span: Span,
+ destination: CPlace<'tcx>,
+ target: Option<BasicBlock>,
+ source_info: mir::SourceInfo,
) {
let intrinsic = fx.tcx.item_name(instance.def_id());
let substs = instance.substs;
- let ret = match destination {
- Some((place, _)) => place,
- None => {
- // Insert non returning intrinsics here
- match intrinsic {
- sym::abort => {
- fx.bcx.ins().trap(TrapCode::User(0));
- }
- sym::transmute => {
- crate::base::codegen_panic(fx, "Transmuting to uninhabited type.", span);
- }
- _ => unimplemented!("unsupported instrinsic {}", intrinsic),
+ let target = if let Some(target) = target {
+ target
+ } else {
+ // Insert non returning intrinsics here
+ match intrinsic {
+ sym::abort => {
+ fx.bcx.ins().trap(TrapCode::User(0));
}
- return;
+ sym::transmute => {
+ crate::base::codegen_panic(fx, "Transmuting to uninhabited type.", source_info);
+ }
+ _ => unimplemented!("unsupported instrinsic {}", intrinsic),
}
+ return;
};
if intrinsic.as_str().starts_with("simd_") {
- self::simd::codegen_simd_intrinsic_call(fx, intrinsic, substs, args, ret, span);
- let ret_block = fx.get_block(destination.expect("SIMD intrinsics don't diverge").1);
+ self::simd::codegen_simd_intrinsic_call(
+ fx,
+ intrinsic,
+ substs,
+ args,
+ destination,
+ source_info.span,
+ );
+ let ret_block = fx.get_block(target);
fx.bcx.ins().jump(ret_block, &[]);
- } else if codegen_float_intrinsic_call(fx, intrinsic, args, ret) {
- let ret_block = fx.get_block(destination.expect("Float intrinsics don't diverge").1);
+ } else if codegen_float_intrinsic_call(fx, intrinsic, args, destination) {
+ let ret_block = fx.get_block(target);
fx.bcx.ins().jump(ret_block, &[]);
} else {
codegen_regular_intrinsic_call(
intrinsic,
substs,
args,
- ret,
- span,
destination,
+ Some(target),
+ source_info,
);
}
}
substs: SubstsRef<'tcx>,
args: &[mir::Operand<'tcx>],
ret: CPlace<'tcx>,
- span: Span,
- destination: Option<(CPlace<'tcx>, BasicBlock)>,
+ destination: Option<BasicBlock>,
+ source_info: mir::SourceInfo,
) {
let usize_layout = fx.layout_of(fx.tcx.types.usize);
intrinsic_match! {
fx, intrinsic, args,
_ => {
- fx.tcx.sess.span_fatal(span, &format!("unsupported intrinsic {}", intrinsic));
+ fx.tcx.sess.span_fatal(source_info.span, &format!("unsupported intrinsic {}", intrinsic));
};
assume, (c _a) {};
crate::base::codegen_panic(
fx,
&format!("attempted to instantiate uninhabited type `{}`", layout.ty),
- span,
+ source_info,
)
});
return;
}
- if intrinsic == sym::assert_zero_valid && !layout.might_permit_raw_init(fx, /*zero:*/ true) {
+ if intrinsic == sym::assert_zero_valid
+ && !layout.might_permit_raw_init(
+ fx,
+ InitKind::Zero,
+ fx.tcx.sess.opts.debugging_opts.strict_init_checks) {
+
with_no_trimmed_paths!({
crate::base::codegen_panic(
fx,
&format!("attempted to zero-initialize type `{}`, which is invalid", layout.ty),
- span,
+ source_info,
);
});
return;
}
- if intrinsic == sym::assert_uninit_valid && !layout.might_permit_raw_init(fx, /*zero:*/ false) {
+ if intrinsic == sym::assert_uninit_valid
+ && !layout.might_permit_raw_init(
+ fx,
+ InitKind::Uninit,
+ fx.tcx.sess.opts.debugging_opts.strict_init_checks) {
+
with_no_trimmed_paths!({
crate::base::codegen_panic(
fx,
&format!("attempted to leave type `{}` uninitialized, which is invalid", layout.ty),
- span,
+ source_info,
)
});
return;
ptr_offset_from | ptr_offset_from_unsigned, (v ptr, v base) {
let ty = substs.type_at(0);
- let isize_layout = fx.layout_of(fx.tcx.types.isize);
let pointee_size: u64 = fx.layout_of(ty).size.bytes();
let diff_bytes = fx.bcx.ins().isub(ptr, base);
// FIXME this can be an exact division.
- let diff = if intrinsic == sym::ptr_offset_from_unsigned {
+ let val = if intrinsic == sym::ptr_offset_from_unsigned {
+ let usize_layout = fx.layout_of(fx.tcx.types.usize);
// Because diff_bytes ULE isize::MAX, this would be fine as signed,
// but unsigned is slightly easier to codegen, so might as well.
- fx.bcx.ins().udiv_imm(diff_bytes, pointee_size as i64)
+ CValue::by_val(fx.bcx.ins().udiv_imm(diff_bytes, pointee_size as i64), usize_layout)
} else {
- fx.bcx.ins().sdiv_imm(diff_bytes, pointee_size as i64)
+ let isize_layout = fx.layout_of(fx.tcx.types.isize);
+ CValue::by_val(fx.bcx.ins().sdiv_imm(diff_bytes, pointee_size as i64), isize_layout)
};
- let val = CValue::by_val(diff, isize_layout);
ret.write_cvalue(fx, val);
};
};
caller_location, () {
- let caller_location = fx.get_caller_location(span);
+ let caller_location = fx.get_caller_location(source_info);
ret.write_cvalue(fx, caller_location);
};
if fx.tcx.is_compiler_builtins(LOCAL_CRATE) {
// special case for compiler-builtins to avoid having to patch it
crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported");
- let ret_block = fx.get_block(destination.unwrap().1);
+ let ret_block = fx.get_block(destination.unwrap());
fx.bcx.ins().jump(ret_block, &[]);
return;
} else {
- fx.tcx.sess.span_fatal(span, "128bit atomics not yet supported");
+ fx.tcx.sess.span_fatal(source_info.span, "128bit atomics not yet supported");
}
}
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => {
- report_atomic_type_validation_error(fx, intrinsic, span, ty);
+ report_atomic_type_validation_error(fx, intrinsic, source_info.span, ty);
return;
}
}
if fx.tcx.is_compiler_builtins(LOCAL_CRATE) {
// special case for compiler-builtins to avoid having to patch it
crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported");
- let ret_block = fx.get_block(destination.unwrap().1);
+ let ret_block = fx.get_block(destination.unwrap());
fx.bcx.ins().jump(ret_block, &[]);
return;
} else {
- fx.tcx.sess.span_fatal(span, "128bit atomics not yet supported");
+ fx.tcx.sess.span_fatal(source_info.span, "128bit atomics not yet supported");
}
}
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => {
- report_atomic_type_validation_error(fx, intrinsic, span, ty);
+ report_atomic_type_validation_error(fx, intrinsic, source_info.span, ty);
return;
}
}
match layout.ty.kind() {
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => {
- report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+ report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return;
}
}
match layout.ty.kind() {
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => {
- report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+ report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return;
}
}
match layout.ty.kind() {
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => {
- report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+ report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return;
}
}
match layout.ty.kind() {
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => {
- report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+ report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return;
}
}
match layout.ty.kind() {
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => {
- report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+ report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return;
}
}
match layout.ty.kind() {
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => {
- report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+ report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return;
}
}
match layout.ty.kind() {
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => {
- report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+ report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return;
}
}
match layout.ty.kind() {
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => {
- report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+ report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return;
}
}
match layout.ty.kind() {
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => {
- report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+ report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return;
}
}
match layout.ty.kind() {
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => {
- report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+ report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return;
}
}
match layout.ty.kind() {
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => {
- report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+ report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return;
}
}
match layout.ty.kind() {
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => {
- report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+ report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return;
}
}
};
}
- let ret_block = fx.get_block(destination.unwrap().1);
+ let ret_block = fx.get_block(destination.unwrap());
fx.bcx.ins().jump(ret_block, &[]);
}