diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-02-02 02:43:33 -0700 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-02-02 02:43:33 -0700 |
| commit | 5ad84e47241cb412a0bfc6619eada1e4c7f4c1ec (patch) | |
| tree | abcb86cbf2cd339582e66bf6603164163af953a8 /src | |
| parent | 6f1a7a0d70d53e7402380ce23a7b1e9c55aefa5c (diff) | |
| download | zig-5ad84e47241cb412a0bfc6619eada1e4c7f4c1ec.tar.gz zig-5ad84e47241cb412a0bfc6619eada1e4c7f4c1ec.zip | |
unreachable causes a trap in debug mode
Diffstat (limited to 'src')
| -rw-r--r-- | src/all_types.hpp | 1 | ||||
| -rw-r--r-- | src/codegen.cpp | 33 |
2 files changed, 32 insertions, 2 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index 65456291e6..1f87ee128e 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -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; diff --git a/src/codegen.cpp b/src/codegen.cpp index b6cf0f2d96..63e1be54e5 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -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); @@ -3085,6 +3109,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; builtin_fn->param_count = 3; |
