mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-18 20:02:22 -07:00
Diverging procedures proc() -> ! (no return)
This commit is contained in:
@@ -299,7 +299,7 @@ foreign {
|
||||
debug_trap :: proc() ---;
|
||||
|
||||
@(link_name="llvm.trap")
|
||||
trap :: proc() ---;
|
||||
trap :: proc() -> ! ---;
|
||||
|
||||
@(link_name="llvm.readcyclecounter")
|
||||
read_cycle_counter :: proc() -> u64 ---;
|
||||
|
||||
@@ -785,6 +785,15 @@ bit_set_type :: proc() {
|
||||
}
|
||||
}
|
||||
|
||||
diverging_procedures :: proc() {
|
||||
// Diverging procedures may never return
|
||||
foo :: proc() -> ! {
|
||||
fmt.println("I'm a diverging procedure");
|
||||
}
|
||||
|
||||
foo();
|
||||
}
|
||||
|
||||
|
||||
main :: proc() {
|
||||
when true {
|
||||
@@ -800,5 +809,6 @@ main :: proc() {
|
||||
cstring_example();
|
||||
deprecated_attribute();
|
||||
bit_set_type();
|
||||
diverging_procedures();
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -1213,13 +1213,17 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
|
||||
GB_ASSERT(proc_type->kind == Type_Proc);
|
||||
// Type *proc_type = c->proc_stack[c->proc_stack.count-1];
|
||||
TypeProc *pt = &proc_type->Proc;
|
||||
if (pt->no_return) {
|
||||
error(rs->token, "Diverging procedures may not return");
|
||||
break;
|
||||
}
|
||||
|
||||
isize result_count = 0;
|
||||
bool has_named_results = pt->has_named_results;
|
||||
if (pt->results) {
|
||||
result_count = proc_type->Proc.results->Tuple.variables.count;
|
||||
}
|
||||
|
||||
|
||||
auto operands = array_make<Operand>(heap_allocator(), 0, 2*rs->results.count);
|
||||
defer (array_free(&operands));
|
||||
|
||||
|
||||
@@ -1951,6 +1951,7 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node,
|
||||
type->Proc.calling_convention = cc;
|
||||
type->Proc.is_polymorphic = pt->generic;
|
||||
type->Proc.specialization_count = specialization_count;
|
||||
type->Proc.no_return = pt->no_return;
|
||||
|
||||
if (param_count > 0) {
|
||||
Entity *end = params->Tuple.variables[param_count-1];
|
||||
|
||||
@@ -1475,6 +1475,9 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
||||
}
|
||||
ir_write_str_lit(f, ")");
|
||||
|
||||
if (proc_type->Proc.no_return) {
|
||||
ir_write_str_lit(f, " noreturn");
|
||||
}
|
||||
ir_print_debug_location(f, m, value, instr->block->proc);
|
||||
|
||||
break;
|
||||
@@ -1624,6 +1627,10 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (proc_type->no_return) {
|
||||
ir_write_str_lit(f, "noreturn ");
|
||||
}
|
||||
|
||||
if (m->generate_debug_info && proc->entity != nullptr && proc->body != nullptr) {
|
||||
irDebugInfo **di_ = map_get(&proc->module->debug_info, hash_pointer(proc->entity));
|
||||
if (di_ != nullptr) {
|
||||
|
||||
+11
-4
@@ -866,7 +866,7 @@ Ast *ast_poly_type(AstFile *f, Token token, Ast *type, Ast *specialization) {
|
||||
}
|
||||
|
||||
|
||||
Ast *ast_proc_type(AstFile *f, Token token, Ast *params, Ast *results, u64 tags, ProcCallingConvention calling_convention, bool generic) {
|
||||
Ast *ast_proc_type(AstFile *f, Token token, Ast *params, Ast *results, u64 tags, ProcCallingConvention calling_convention, bool generic, bool no_return) {
|
||||
Ast *result = alloc_ast_node(f, Ast_ProcType);
|
||||
result->ProcType.token = token;
|
||||
result->ProcType.params = params;
|
||||
@@ -874,6 +874,7 @@ Ast *ast_proc_type(AstFile *f, Token token, Ast *params, Ast *results, u64 tags,
|
||||
result->ProcType.tags = tags;
|
||||
result->ProcType.calling_convention = calling_convention;
|
||||
result->ProcType.generic = generic;
|
||||
result->ProcType.no_return = no_return;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2620,11 +2621,16 @@ Ast *parse_block_stmt(AstFile *f, b32 is_when) {
|
||||
|
||||
|
||||
|
||||
Ast *parse_results(AstFile *f) {
|
||||
Ast *parse_results(AstFile *f, bool *no_return) {
|
||||
if (!allow_token(f, Token_ArrowRight)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (allow_token(f, Token_Not)) {
|
||||
if (no_return) *no_return = true;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
isize prev_level = f->expr_level;
|
||||
defer (f->expr_level = prev_level);
|
||||
// f->expr_level = -1;
|
||||
@@ -2661,6 +2667,7 @@ ProcCallingConvention string_to_calling_convention(String s) {
|
||||
Ast *parse_proc_type(AstFile *f, Token proc_token) {
|
||||
Ast *params = nullptr;
|
||||
Ast *results = nullptr;
|
||||
bool no_return = false;
|
||||
|
||||
ProcCallingConvention cc = ProcCC_Invalid;
|
||||
if (f->curr_token.kind == Token_String) {
|
||||
@@ -2684,7 +2691,7 @@ Ast *parse_proc_type(AstFile *f, Token proc_token) {
|
||||
expect_token(f, Token_OpenParen);
|
||||
params = parse_field_list(f, nullptr, FieldFlag_Signature, Token_CloseParen, true, true);
|
||||
expect_token_after(f, Token_CloseParen, "parameter list");
|
||||
results = parse_results(f);
|
||||
results = parse_results(f, &no_return);
|
||||
|
||||
u64 tags = 0;
|
||||
parse_proc_tags(f, &tags);
|
||||
@@ -2710,7 +2717,7 @@ Ast *parse_proc_type(AstFile *f, Token proc_token) {
|
||||
}
|
||||
}
|
||||
end:
|
||||
return ast_proc_type(f, proc_token, params, results, tags, cc, is_generic);
|
||||
return ast_proc_type(f, proc_token, params, results, tags, cc, is_generic, no_return);
|
||||
}
|
||||
|
||||
Ast *parse_var_type(AstFile *f, bool allow_ellipsis, bool allow_type_token) {
|
||||
|
||||
@@ -446,6 +446,7 @@ AST_KIND(_TypeBegin, "", bool) \
|
||||
u64 tags; \
|
||||
ProcCallingConvention calling_convention; \
|
||||
bool generic; \
|
||||
bool no_return; \
|
||||
}) \
|
||||
AST_KIND(PointerType, "pointer type", struct { \
|
||||
Token token; \
|
||||
|
||||
@@ -174,6 +174,7 @@ struct TypeUnion {
|
||||
bool is_poly_specialized; \
|
||||
bool has_proc_default_values; \
|
||||
bool has_named_results; \
|
||||
bool no_return; \
|
||||
isize specialization_count; \
|
||||
ProcCallingConvention calling_convention; \
|
||||
}) \
|
||||
|
||||
Reference in New Issue
Block a user