Remove most trap functions and remove all trapnz usages
This commit is contained in:
parent
526553e4a3
commit
fa6480e43d
18
src/base.rs
18
src/base.rs
@ -90,7 +90,8 @@ pub(crate) fn codegen_fn<'tcx>(
|
||||
if !crate::constant::check_constants(&mut fx) {
|
||||
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
|
||||
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
|
||||
crate::trap::trap_unreachable(&mut fx, "compilation should have been aborted");
|
||||
// compilation should have been aborted
|
||||
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
|
||||
} else if arg_uninhabited {
|
||||
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
|
||||
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
|
||||
@ -457,17 +458,8 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
|
||||
template,
|
||||
operands,
|
||||
*options,
|
||||
*destination,
|
||||
);
|
||||
|
||||
match *destination {
|
||||
Some(destination) => {
|
||||
let destination_block = fx.get_block(destination);
|
||||
fx.bcx.ins().jump(destination_block, &[]);
|
||||
}
|
||||
None => {
|
||||
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
|
||||
}
|
||||
}
|
||||
}
|
||||
TerminatorKind::Resume | TerminatorKind::Abort => {
|
||||
// FIXME implement unwinding
|
||||
@ -711,9 +703,7 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
Rvalue::Discriminant(place) => {
|
||||
let place = codegen_place(fx, place);
|
||||
let value = place.to_cvalue(fx);
|
||||
let discr =
|
||||
crate::discriminant::codegen_get_discriminant(fx, value, dest_layout);
|
||||
lval.write_cvalue(fx, discr);
|
||||
crate::discriminant::codegen_get_discriminant(fx, lval, value, dest_layout);
|
||||
}
|
||||
Rvalue::Repeat(ref operand, times) => {
|
||||
let operand = codegen_operand(fx, operand);
|
||||
|
@ -62,16 +62,14 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
|
||||
|
||||
pub(crate) fn codegen_get_discriminant<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
dest: CPlace<'tcx>,
|
||||
value: CValue<'tcx>,
|
||||
dest_layout: TyAndLayout<'tcx>,
|
||||
) -> CValue<'tcx> {
|
||||
) {
|
||||
let layout = value.layout();
|
||||
|
||||
if layout.abi == Abi::Uninhabited {
|
||||
let true_ = fx.bcx.ins().iconst(types::I32, 1);
|
||||
fx.bcx.ins().trapnz(true_, TrapCode::UnreachableCodeReached);
|
||||
// Return a dummy value
|
||||
return CValue::by_ref(Pointer::const_addr(fx, 0), dest_layout);
|
||||
if layout.abi.is_uninhabited() {
|
||||
return;
|
||||
}
|
||||
|
||||
let (tag_scalar, tag_field, tag_encoding) = match &layout.variants {
|
||||
@ -89,7 +87,9 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
|
||||
} else {
|
||||
ty::ScalarInt::try_from_uint(discr_val, dest_layout.size).unwrap()
|
||||
};
|
||||
return CValue::const_val(fx, dest_layout, discr_val);
|
||||
let res = CValue::const_val(fx, dest_layout, discr_val);
|
||||
dest.write_cvalue(fx, res);
|
||||
return;
|
||||
}
|
||||
Variants::Multiple { tag, tag_field, tag_encoding, variants: _ } => {
|
||||
(tag, *tag_field, tag_encoding)
|
||||
@ -110,7 +110,8 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
|
||||
_ => false,
|
||||
};
|
||||
let val = clif_intcast(fx, tag, cast_to, signed);
|
||||
CValue::by_val(val, dest_layout)
|
||||
let res = CValue::by_val(val, dest_layout);
|
||||
dest.write_cvalue(fx, res);
|
||||
}
|
||||
TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => {
|
||||
// Rebase from niche values to discriminants, and check
|
||||
@ -170,7 +171,8 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
|
||||
|
||||
let dataful_variant = fx.bcx.ins().iconst(cast_to, i64::from(dataful_variant.as_u32()));
|
||||
let discr = fx.bcx.ins().select(is_niche, niche_discr, dataful_variant);
|
||||
CValue::by_val(discr, dest_layout)
|
||||
let res = CValue::by_val(discr, dest_layout);
|
||||
dest.write_cvalue(fx, res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,13 +15,13 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
||||
template: &[InlineAsmTemplatePiece],
|
||||
operands: &[InlineAsmOperand<'tcx>],
|
||||
options: InlineAsmOptions,
|
||||
destination: Option<mir::BasicBlock>,
|
||||
) {
|
||||
// FIXME add .eh_frame unwind info directives
|
||||
|
||||
if !template.is_empty() {
|
||||
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
|
||||
let true_ = fx.bcx.ins().iconst(types::I32, 1);
|
||||
fx.bcx.ins().trapnz(true_, TrapCode::User(1));
|
||||
fx.bcx.ins().trap(TrapCode::User(1));
|
||||
return;
|
||||
} else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
|
||||
&& matches!(
|
||||
@ -101,12 +101,16 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
||||
ebx_place.write_cvalue(fx, CValue::by_val(ebx, fx.layout_of(fx.tcx.types.u32)));
|
||||
ecx_place.write_cvalue(fx, CValue::by_val(ecx, fx.layout_of(fx.tcx.types.u32)));
|
||||
edx_place.write_cvalue(fx, CValue::by_val(edx, fx.layout_of(fx.tcx.types.u32)));
|
||||
let destination_block = fx.get_block(destination.unwrap());
|
||||
fx.bcx.ins().jump(destination_block, &[]);
|
||||
return;
|
||||
} else if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
|
||||
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
|
||||
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
|
||||
return;
|
||||
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
|
||||
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,6 +179,16 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
||||
}
|
||||
|
||||
call_inline_asm(fx, &asm_name, asm_gen.stack_slot_size, inputs, outputs);
|
||||
|
||||
match destination {
|
||||
Some(destination) => {
|
||||
let destination_block = fx.get_block(destination);
|
||||
fx.bcx.ins().jump(destination_block, &[]);
|
||||
}
|
||||
None => {
|
||||
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct InlineAssemblyGenerator<'a, 'tcx> {
|
||||
|
@ -62,7 +62,7 @@ pub(crate) fn codegen_cpuid_call<'tcx>(
|
||||
fx.bcx.ins().jump(dest, &[zero, zero, proc_info_ecx, proc_info_edx]);
|
||||
|
||||
fx.bcx.switch_to_block(unsupported_leaf);
|
||||
crate::trap::trap_unreachable(
|
||||
crate::trap::trap_unimplemented(
|
||||
fx,
|
||||
"__cpuid_count arch intrinsic doesn't yet support specified leaf",
|
||||
);
|
||||
|
@ -139,6 +139,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
|
||||
.sess
|
||||
.warn(&format!("unsupported llvm intrinsic {}; replacing with trap", intrinsic));
|
||||
crate::trap::trap_unimplemented(fx, intrinsic);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ fn report_atomic_type_validation_error<'tcx>(
|
||||
),
|
||||
);
|
||||
// Prevent verifier error
|
||||
crate::trap::trap_unreachable(fx, "compilation should not have succeeded");
|
||||
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
|
||||
}
|
||||
|
||||
pub(crate) fn clif_vector_type<'tcx>(tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx>) -> Option<Type> {
|
||||
@ -849,8 +849,6 @@ fn swap(bcx: &mut FunctionBuilder<'_>, v: Value) -> Value {
|
||||
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());
|
||||
fx.bcx.ins().jump(ret_block, &[]);
|
||||
return;
|
||||
} else {
|
||||
fx.tcx
|
||||
@ -882,8 +880,6 @@ fn swap(bcx: &mut FunctionBuilder<'_>, v: Value) -> Value {
|
||||
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());
|
||||
fx.bcx.ins().jump(ret_block, &[]);
|
||||
return;
|
||||
} else {
|
||||
fx.tcx
|
||||
|
@ -14,7 +14,7 @@ fn report_simd_type_validation_error(
|
||||
) {
|
||||
fx.tcx.sess.span_err(span, &format!("invalid monomorphization of `{}` intrinsic: expected SIMD input type, found non-SIMD `{}`", intrinsic, ty));
|
||||
// Prevent verifier error
|
||||
crate::trap::trap_unreachable(fx, "compilation should not have succeeded");
|
||||
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
|
||||
}
|
||||
|
||||
pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||
@ -157,7 +157,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||
),
|
||||
);
|
||||
// Prevent verifier error
|
||||
crate::trap::trap_unreachable(fx, "compilation should not have succeeded");
|
||||
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -274,12 +274,17 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||
idx_const
|
||||
} else {
|
||||
fx.tcx.sess.span_warn(span, "Index argument for `simd_extract` is not a constant");
|
||||
let res = crate::trap::trap_unimplemented_ret_value(
|
||||
let trap_block = fx.bcx.create_block();
|
||||
let dummy_block = fx.bcx.create_block();
|
||||
let true_ = fx.bcx.ins().iconst(types::I8, 1);
|
||||
fx.bcx.ins().brnz(true_, trap_block, &[]);
|
||||
fx.bcx.ins().jump(dummy_block, &[]);
|
||||
fx.bcx.switch_to_block(trap_block);
|
||||
crate::trap::trap_unimplemented(
|
||||
fx,
|
||||
ret.layout(),
|
||||
"Index argument for `simd_extract` is not a constant",
|
||||
);
|
||||
ret.write_cvalue(fx, res);
|
||||
fx.bcx.switch_to_block(dummy_block);
|
||||
return;
|
||||
};
|
||||
|
||||
|
25
src/trap.rs
25
src/trap.rs
@ -25,33 +25,10 @@ fn codegen_print(fx: &mut FunctionCx<'_, '_, '_>, msg: &str) {
|
||||
fx.bcx.ins().call(puts, &[msg_ptr]);
|
||||
}
|
||||
|
||||
/// Use this for example when a function call should never return. This will fill the current block,
|
||||
/// so you can **not** add instructions to it afterwards.
|
||||
///
|
||||
/// Trap code: user65535
|
||||
pub(crate) fn trap_unreachable(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef<str>) {
|
||||
codegen_print(fx, msg.as_ref());
|
||||
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
|
||||
}
|
||||
/// Use this when something is unimplemented, but `libcore` or `libstd` requires it to codegen.
|
||||
/// Unlike `trap_unreachable` this will not fill the current block, so you **must** add instructions
|
||||
/// to it afterwards.
|
||||
///
|
||||
/// Trap code: user65535
|
||||
pub(crate) fn trap_unimplemented(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef<str>) {
|
||||
codegen_print(fx, msg.as_ref());
|
||||
let true_ = fx.bcx.ins().iconst(types::I32, 1);
|
||||
fx.bcx.ins().trapnz(true_, TrapCode::User(!0));
|
||||
}
|
||||
|
||||
/// Like `trap_unimplemented` but returns a fake value of the specified type.
|
||||
///
|
||||
/// Trap code: user65535
|
||||
pub(crate) fn trap_unimplemented_ret_value<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
dest_layout: TyAndLayout<'tcx>,
|
||||
msg: impl AsRef<str>,
|
||||
) -> CValue<'tcx> {
|
||||
trap_unimplemented(fx, msg);
|
||||
CValue::by_ref(Pointer::const_addr(fx, 0), dest_layout)
|
||||
fx.bcx.ins().trap(TrapCode::User(!0));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user