unreachable causes a trap in debug mode

This commit is contained in:
Andrew Kelley
2016-02-02 02:43:33 -07:00
parent 6f1a7a0d70
commit 5ad84e4724
5 changed files with 38 additions and 7 deletions

View File

@@ -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;