From 06f2f4d64b63cf78a3ff77cc64dbc822123f454d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 13 Sep 2016 16:46:27 -0400 Subject: change `unreachable{}` to `@unreachable()` instead of a container init expression, it's a builtin function call. --- src/all_types.hpp | 1 + src/analyze.cpp | 9 ++------- src/codegen.cpp | 26 +++++++++++++++++--------- src/eval.cpp | 18 +++++++++++------- 4 files changed, 31 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/all_types.hpp b/src/all_types.hpp index d5b24b121d..71bc596f81 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1174,6 +1174,7 @@ enum BuiltinFnId { BuiltinFnIdDivExact, BuiltinFnIdTruncate, BuiltinFnIdIntType, + BuiltinFnIdUnreachable, }; struct BuiltinFnEntry { diff --git a/src/analyze.cpp b/src/analyze.cpp index 3ed246d1b5..b39bc584ac 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2677,13 +2677,6 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry } else { return resolve_expr_const_val_as_void(g, node); } - } else if (container_type->id == TypeTableEntryIdUnreachable) { - if (container_init_expr->entries.length != 0) { - add_node_error(g, node, buf_sprintf("unreachable expression expects no arguments")); - return g->builtin_types.entry_invalid; - } else { - return container_type; - } } else { add_node_error(g, node, buf_sprintf("type '%s' does not support %s initialization syntax", @@ -5435,6 +5428,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry return analyze_compile_err(g, import, context, node); case BuiltinFnIdIntType: return analyze_int_type(g, import, context, node); + case BuiltinFnIdUnreachable: + return g->builtin_types.entry_unreachable; } zig_unreachable(); } diff --git a/src/codegen.cpp b/src/codegen.cpp index 41a1a394cd..ddf06b7eef 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -497,6 +497,20 @@ static LLVMValueRef gen_truncate(CodeGen *g, AstNode *node) { return LLVMBuildTrunc(g->builder, src_val, dest_type->type_ref, ""); } +static LLVMValueRef gen_unreachable(CodeGen *g, AstNode *node) { + assert(node->type == NodeTypeFnCallExpr); + + set_debug_source_node(g, node); + + if (want_debug_safety(g, node) || g->is_test_build) { + gen_debug_safety_crash(g); + } else { + LLVMBuildUnreachable(g->builder); + } + + return nullptr; +} + static LLVMValueRef gen_shl_with_overflow(CodeGen *g, AstNode *node) { assert(node->type == NodeTypeFnCallExpr); @@ -689,6 +703,8 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { return gen_div_exact(g, node); case BuiltinFnIdTruncate: return gen_truncate(g, node); + case BuiltinFnIdUnreachable: + return gen_unreachable(g, node); } zig_unreachable(); } @@ -2949,15 +2965,6 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) { } return tmp_struct_ptr; - } else if (type_entry->id == TypeTableEntryIdUnreachable) { - assert(node->data.container_init_expr.entries.length == 0); - set_debug_source_node(g, node); - if (want_debug_safety(g, node) || g->is_test_build) { - gen_debug_safety_crash(g); - } else { - LLVMBuildUnreachable(g->builder); - } - return nullptr; } else if (type_entry->id == TypeTableEntryIdVoid) { assert(node->data.container_init_expr.entries.length == 0); return nullptr; @@ -4859,6 +4866,7 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn_with_arg_count(g, BuiltinFnIdTruncate, "truncate", 2); create_builtin_fn_with_arg_count(g, BuiltinFnIdCompileErr, "compileError", 1); create_builtin_fn_with_arg_count(g, BuiltinFnIdIntType, "intType", 2); + create_builtin_fn_with_arg_count(g, BuiltinFnIdUnreachable, "unreachable", 0); } static void init(CodeGen *g, Buf *source_path) { diff --git a/src/eval.cpp b/src/eval.cpp index 1e71fd262b..79d3079adc 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -491,13 +491,6 @@ static bool eval_container_init_expr(EvalFn *ef, AstNode *node, ConstExprValue * } } else if (container_type->id == TypeTableEntryIdVoid) { return false; - } else if (container_type->id == TypeTableEntryIdUnreachable) { - ef->root->abort = true; - ErrorMsg *msg = add_node_error(ef->root->codegen, ef->root->fn->fn_def_node, - buf_sprintf("function evaluation reached unreachable expression")); - add_error_note(ef->root->codegen, msg, ef->root->call_node, buf_sprintf("called from here")); - add_error_note(ef->root->codegen, msg, node, buf_sprintf("unreachable expression here")); - return true; } else if (container_type->id == TypeTableEntryIdStruct && container_type->data.structure.is_slice && kind == ContainerInitKindArray) @@ -791,6 +784,15 @@ static bool eval_div_exact(EvalFn *ef, AstNode *node, ConstExprValue *out_val) { return false; } +static bool eval_unreachable(EvalFn *ef, AstNode *node, ConstExprValue *out_val) { + ef->root->abort = true; + ErrorMsg *msg = add_node_error(ef->root->codegen, ef->root->fn->fn_def_node, + buf_sprintf("function evaluation reached unreachable expression")); + add_error_note(ef->root->codegen, msg, ef->root->call_node, buf_sprintf("called from here")); + add_error_note(ef->root->codegen, msg, node, buf_sprintf("unreachable expression here")); + return true; +} + static bool eval_fn_with_overflow(EvalFn *ef, AstNode *node, ConstExprValue *out_val, bool (*bignum_fn)(BigNum *dest, BigNum *op1, BigNum *op2)) { @@ -851,6 +853,8 @@ static bool eval_fn_call_builtin(EvalFn *ef, AstNode *node, ConstExprValue *out_ return false; case BuiltinFnIdDivExact: return eval_div_exact(ef, node, out_val); + case BuiltinFnIdUnreachable: + return eval_unreachable(ef, node, out_val); case BuiltinFnIdMemcpy: case BuiltinFnIdMemset: case BuiltinFnIdSizeof: -- cgit v1.2.3