aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/all_types.hpp1
-rw-r--r--src/analyze.cpp9
-rw-r--r--src/codegen.cpp26
-rw-r--r--src/eval.cpp18
4 files changed, 31 insertions, 23 deletions
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: