harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 6c6bcd46c2d73f2f4ebacbd38d8bdb1dc1e62490
parent 73be71e38e2f009914a8f1c2994377da02805581
Author: Steven Guikal <void@fluix.dev>
Date:   Wed, 10 Mar 2021 14:08:45 -0500

Call deferred functions before noreturn functions

Diffstat:
Msrc/gen.c | 11+++++++++++
Mtests/16-defer.ha | 16++++++++++++++++
2 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -1044,6 +1044,17 @@ gen_expr_call(struct gen_context *ctx, ftype->func.result, true), "returns.%d"); call.out = qval_dup(&result); } + if (ftype->func.flags & FN_NORETURN) { + struct gen_scope_context *scope = ctx->scope; + while (scope) { + gen_defers(ctx, scope); + if (scope->class == SCOPE_FUNC) { + break; + } + scope = scope->parent; + } + assert(scope); + } while (carg) { arg = *next = xcalloc(1, sizeof(struct qbe_arguments)); diff --git a/tests/16-defer.ha b/tests/16-defer.ha @@ -1,3 +1,5 @@ +use rt; + let x: int = 10; fn basics() void = { @@ -47,10 +49,24 @@ fn control() void = { assert(x == 1); }; +fn noreturn() void = { + defer x = 30; + for (true) { + defer x = 20; + exit(); + }; +}; + +@noreturn fn exit() void = { + assert(x == 30); + rt::exit(0); +}; + export fn main() void = { basics(); assert(x == 20); scope(); loops(); control(); + noreturn(); };