harec

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

commit 934349a5b9b12e914f422b23af207bb6c70a88c2
parent 3f6c4d6ec990739d04b2ccd04151087869c39581
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri, 13 Aug 2021 14:52:56 +0200

gen: abort when reaching supposedly unreachable code

This can be expanded

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Minclude/gen.h | 1+
Mrt/abort.ha | 1+
Msrc/gen.c | 16++++++++++++++++
3 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/include/gen.h b/include/gen.h @@ -11,6 +11,7 @@ enum fixed_aborts { ABORT_TYPE_ASSERTION = 1, ABORT_ALLOC_FAILURE = 2, ABORT_STATIC_EXCEEDED = 3, + ABORT_UNREACHABLE = 4, }; struct gen_arch { diff --git a/rt/abort.ha b/rt/abort.ha @@ -11,6 +11,7 @@ const reasons: [_]str = [ "slice or array access out of bounds", // 0 "type assertion failed", // 1 "out of memory", // 2 + "unreachable code", // 3 ]; export @noreturn fn abort_fixed(loc: str, i: int) void = { diff --git a/src/gen.c b/src/gen.c @@ -2107,8 +2107,16 @@ next: if (_default) { bval = gen_expr_with(ctx, _default->value, out); branch_copyresult(ctx, bval, gvout, out); + if (!_default->value->terminates) { + pushi(ctx->current, NULL, Q_JMP, &bout, NULL); + } } + struct qbe_statement labort; + mklabel(ctx, &labort, ".%d"); + push(&ctx->current->body, &labort); + gen_fixed_abort(ctx, expr->loc, ABORT_UNREACHABLE); + push(&ctx->current->body, &lout); return gvout; } @@ -2294,8 +2302,16 @@ gen_expr_switch_with(struct gen_context *ctx, if (_default) { bval = gen_expr_with(ctx, _default->value, out); branch_copyresult(ctx, bval, gvout, out); + if (!_default->value->terminates) { + pushi(ctx->current, NULL, Q_JMP, &bout, NULL); + } } + struct qbe_statement labort; + mklabel(ctx, &labort, ".%d"); + push(&ctx->current->body, &labort); + gen_fixed_abort(ctx, expr->loc, ABORT_UNREACHABLE); + push(&ctx->current->body, &lout); return gvout; }