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:
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;
}