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) {
|
if !crate::constant::check_constants(&mut fx) {
|
||||||
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
|
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
|
||||||
fx.bcx.switch_to_block(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 {
|
} else if arg_uninhabited {
|
||||||
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
|
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
|
||||||
fx.bcx.switch_to_block(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,
|
template,
|
||||||
operands,
|
operands,
|
||||||
*options,
|
*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 => {
|
TerminatorKind::Resume | TerminatorKind::Abort => {
|
||||||
// FIXME implement unwinding
|
// FIXME implement unwinding
|
||||||
@ -711,9 +703,7 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
|
|||||||
Rvalue::Discriminant(place) => {
|
Rvalue::Discriminant(place) => {
|
||||||
let place = codegen_place(fx, place);
|
let place = codegen_place(fx, place);
|
||||||
let value = place.to_cvalue(fx);
|
let value = place.to_cvalue(fx);
|
||||||
let discr =
|
crate::discriminant::codegen_get_discriminant(fx, lval, value, dest_layout);
|
||||||
crate::discriminant::codegen_get_discriminant(fx, value, dest_layout);
|
|
||||||
lval.write_cvalue(fx, discr);
|
|
||||||
}
|
}
|
||||||
Rvalue::Repeat(ref operand, times) => {
|
Rvalue::Repeat(ref operand, times) => {
|
||||||
let operand = codegen_operand(fx, operand);
|
let operand = codegen_operand(fx, operand);
|
||||||
|
@ -62,16 +62,14 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
|
|||||||
|
|
||||||
pub(crate) fn codegen_get_discriminant<'tcx>(
|
pub(crate) fn codegen_get_discriminant<'tcx>(
|
||||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
|
dest: CPlace<'tcx>,
|
||||||
value: CValue<'tcx>,
|
value: CValue<'tcx>,
|
||||||
dest_layout: TyAndLayout<'tcx>,
|
dest_layout: TyAndLayout<'tcx>,
|
||||||
) -> CValue<'tcx> {
|
) {
|
||||||
let layout = value.layout();
|
let layout = value.layout();
|
||||||
|
|
||||||
if layout.abi == Abi::Uninhabited {
|
if layout.abi.is_uninhabited() {
|
||||||
let true_ = fx.bcx.ins().iconst(types::I32, 1);
|
return;
|
||||||
fx.bcx.ins().trapnz(true_, TrapCode::UnreachableCodeReached);
|
|
||||||
// Return a dummy value
|
|
||||||
return CValue::by_ref(Pointer::const_addr(fx, 0), dest_layout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let (tag_scalar, tag_field, tag_encoding) = match &layout.variants {
|
let (tag_scalar, tag_field, tag_encoding) = match &layout.variants {
|
||||||
@ -89,7 +87,9 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
|
|||||||
} else {
|
} else {
|
||||||
ty::ScalarInt::try_from_uint(discr_val, dest_layout.size).unwrap()
|
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: _ } => {
|
Variants::Multiple { tag, tag_field, tag_encoding, variants: _ } => {
|
||||||
(tag, *tag_field, tag_encoding)
|
(tag, *tag_field, tag_encoding)
|
||||||
@ -110,7 +110,8 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
|
|||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
let val = clif_intcast(fx, tag, cast_to, signed);
|
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 } => {
|
TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => {
|
||||||
// Rebase from niche values to discriminants, and check
|
// 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 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);
|
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],
|
template: &[InlineAsmTemplatePiece],
|
||||||
operands: &[InlineAsmOperand<'tcx>],
|
operands: &[InlineAsmOperand<'tcx>],
|
||||||
options: InlineAsmOptions,
|
options: InlineAsmOptions,
|
||||||
|
destination: Option<mir::BasicBlock>,
|
||||||
) {
|
) {
|
||||||
// FIXME add .eh_frame unwind info directives
|
// FIXME add .eh_frame unwind info directives
|
||||||
|
|
||||||
if !template.is_empty() {
|
if !template.is_empty() {
|
||||||
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
|
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
|
||||||
let true_ = fx.bcx.ins().iconst(types::I32, 1);
|
fx.bcx.ins().trap(TrapCode::User(1));
|
||||||
fx.bcx.ins().trapnz(true_, TrapCode::User(1));
|
|
||||||
return;
|
return;
|
||||||
} else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
|
} else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
|
||||||
&& matches!(
|
&& 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)));
|
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)));
|
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)));
|
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;
|
return;
|
||||||
} else if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
|
} else if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
|
||||||
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
|
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
|
||||||
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
|
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
|
||||||
|
return;
|
||||||
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
|
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
|
||||||
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
|
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);
|
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> {
|
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.ins().jump(dest, &[zero, zero, proc_info_ecx, proc_info_edx]);
|
||||||
|
|
||||||
fx.bcx.switch_to_block(unsupported_leaf);
|
fx.bcx.switch_to_block(unsupported_leaf);
|
||||||
crate::trap::trap_unreachable(
|
crate::trap::trap_unimplemented(
|
||||||
fx,
|
fx,
|
||||||
"__cpuid_count arch intrinsic doesn't yet support specified leaf",
|
"__cpuid_count arch intrinsic doesn't yet support specified leaf",
|
||||||
);
|
);
|
||||||
|
@ -139,6 +139,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
|
|||||||
.sess
|
.sess
|
||||||
.warn(&format!("unsupported llvm intrinsic {}; replacing with trap", intrinsic));
|
.warn(&format!("unsupported llvm intrinsic {}; replacing with trap", intrinsic));
|
||||||
crate::trap::trap_unimplemented(fx, intrinsic);
|
crate::trap::trap_unimplemented(fx, intrinsic);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ fn report_atomic_type_validation_error<'tcx>(
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
// Prevent verifier error
|
// 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> {
|
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) {
|
if fx.tcx.is_compiler_builtins(LOCAL_CRATE) {
|
||||||
// special case for compiler-builtins to avoid having to patch it
|
// special case for compiler-builtins to avoid having to patch it
|
||||||
crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported");
|
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;
|
return;
|
||||||
} else {
|
} else {
|
||||||
fx.tcx
|
fx.tcx
|
||||||
@ -882,8 +880,6 @@ fn swap(bcx: &mut FunctionBuilder<'_>, v: Value) -> Value {
|
|||||||
if fx.tcx.is_compiler_builtins(LOCAL_CRATE) {
|
if fx.tcx.is_compiler_builtins(LOCAL_CRATE) {
|
||||||
// special case for compiler-builtins to avoid having to patch it
|
// special case for compiler-builtins to avoid having to patch it
|
||||||
crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported");
|
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;
|
return;
|
||||||
} else {
|
} else {
|
||||||
fx.tcx
|
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));
|
fx.tcx.sess.span_err(span, &format!("invalid monomorphization of `{}` intrinsic: expected SIMD input type, found non-SIMD `{}`", intrinsic, ty));
|
||||||
// Prevent verifier error
|
// 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>(
|
pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||||
@ -157,7 +157,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
// Prevent verifier error
|
// Prevent verifier error
|
||||||
crate::trap::trap_unreachable(fx, "compilation should not have succeeded");
|
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,12 +274,17 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
|||||||
idx_const
|
idx_const
|
||||||
} else {
|
} else {
|
||||||
fx.tcx.sess.span_warn(span, "Index argument for `simd_extract` is not a constant");
|
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,
|
fx,
|
||||||
ret.layout(),
|
|
||||||
"Index argument for `simd_extract` is not a constant",
|
"Index argument for `simd_extract` is not a constant",
|
||||||
);
|
);
|
||||||
ret.write_cvalue(fx, res);
|
fx.bcx.switch_to_block(dummy_block);
|
||||||
return;
|
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]);
|
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.
|
/// 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
|
/// Trap code: user65535
|
||||||
pub(crate) fn trap_unimplemented(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef<str>) {
|
pub(crate) fn trap_unimplemented(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef<str>) {
|
||||||
codegen_print(fx, msg.as_ref());
|
codegen_print(fx, msg.as_ref());
|
||||||
let true_ = fx.bcx.ins().iconst(types::I32, 1);
|
fx.bcx.ins().trap(TrapCode::User(!0));
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user