mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
unreachable causes a trap in debug mode
This commit is contained in:
parent
6f1a7a0d70
commit
5ad84e4724
@ -7,7 +7,7 @@ if exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
syn keyword zigStorage const var extern volatile export pub noalias
|
||||
syn keyword zigStorage const var extern volatile export pub noalias inline
|
||||
syn keyword zigStructure struct enum
|
||||
syn keyword zigStatement goto break return continue asm defer
|
||||
syn keyword zigConditional if else switch
|
||||
|
||||
@ -1097,6 +1097,7 @@ struct CodeGen {
|
||||
ImportTableEntry *bootstrap_import;
|
||||
LLVMValueRef memcpy_fn_val;
|
||||
LLVMValueRef memset_fn_val;
|
||||
LLVMValueRef trap_fn_val;
|
||||
bool error_during_imports;
|
||||
uint32_t next_node_index;
|
||||
uint32_t next_error_index;
|
||||
|
||||
@ -991,9 +991,30 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
|
||||
TypeTableEntry *expr_type = get_expr_type(expr_node);
|
||||
assert(expr_type->id == TypeTableEntryIdErrorUnion);
|
||||
TypeTableEntry *child_type = expr_type->data.error.child_type;
|
||||
// TODO in debug mode, put a panic here if the error is not 0
|
||||
|
||||
if (g->build_type != CodeGenBuildTypeRelease) {
|
||||
LLVMValueRef err_val;
|
||||
if (child_type->size_in_bits > 0) {
|
||||
add_debug_source_node(g, node);
|
||||
LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, "");
|
||||
err_val = LLVMBuildLoad(g->builder, err_val_ptr, "");
|
||||
} else {
|
||||
err_val = expr_val;
|
||||
}
|
||||
LLVMValueRef zero = LLVMConstNull(g->err_tag_type->type_ref);
|
||||
LLVMValueRef cond_val = LLVMBuildICmp(g->builder, LLVMIntEQ, err_val, zero, "");
|
||||
LLVMBasicBlockRef err_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrError");
|
||||
LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrOk");
|
||||
LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block);
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, err_block);
|
||||
LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");
|
||||
LLVMBuildUnreachable(g->builder);
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, ok_block);
|
||||
}
|
||||
|
||||
if (child_type->size_in_bits > 0) {
|
||||
add_debug_source_node(g, node);
|
||||
LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, "");
|
||||
if (handle_is_ptr(child_type)) {
|
||||
return child_val_ptr;
|
||||
@ -1898,6 +1919,9 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) {
|
||||
} else if (type_entry->id == TypeTableEntryIdUnreachable) {
|
||||
assert(node->data.container_init_expr.entries.length == 0);
|
||||
add_debug_source_node(g, node);
|
||||
if (g->build_type != CodeGenBuildTypeRelease) {
|
||||
LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");
|
||||
}
|
||||
return LLVMBuildUnreachable(g->builder);
|
||||
} else if (type_entry->id == TypeTableEntryIdVoid) {
|
||||
assert(node->data.container_init_expr.entries.length == 0);
|
||||
@ -3084,6 +3108,11 @@ static BuiltinFnEntry *create_builtin_fn_with_arg_count(CodeGen *g, BuiltinFnId
|
||||
}
|
||||
|
||||
static void define_builtin_fns(CodeGen *g) {
|
||||
{
|
||||
LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), nullptr, 0, false);
|
||||
g->trap_fn_val = LLVMAddFunction(g->module, "llvm.debugtrap", fn_type);
|
||||
assert(LLVMGetIntrinsicID(g->trap_fn_val));
|
||||
}
|
||||
{
|
||||
BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy");
|
||||
builtin_fn->return_type = g->builtin_types.entry_void;
|
||||
|
||||
@ -27,3 +27,8 @@ pub fn f64_is_nan(f: f64) -> bool {
|
||||
pub fn f64_is_inf(f: f64) -> bool {
|
||||
f == f64_get_neg_inf() || f == f64_get_pos_inf()
|
||||
}
|
||||
|
||||
pub fn min_isize(x: isize, y: isize) -> isize {
|
||||
if (x < y) x else y
|
||||
}
|
||||
|
||||
|
||||
@ -372,7 +372,3 @@ pub fn buf_print_f64(out_buf: []u8, x: f64, decimals: isize) -> isize {
|
||||
|
||||
len
|
||||
}
|
||||
|
||||
fn min_isize(x: isize, y: isize) -> isize {
|
||||
if (x < y) x else y
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user