commit f40b930cd99c4a3d3e0bf2b1acff79939519f8da
parent 7f5ecdada36bf67187d1b7e2b624df9d1d2264eb
Author: Alexey Yerin <yyp@disroot.org>
Date: Mon, 9 Aug 2021 10:41:54 +0300
gen: implement bound checks for slicing operation
Signed-off-by: Alexey Yerin <yyp@disroot.org>
Diffstat:
1 file changed, 17 insertions(+), 0 deletions(-)
diff --git a/src/gen.c b/src/gen.c
@@ -1522,6 +1522,23 @@ gen_expr_slice_at(struct gen_context *ctx,
struct qbe_value qstart = mkqval(ctx, &start);
struct qbe_value qend = mkqval(ctx, &end);
+
+ struct qbe_value start_oob = mkqtmp(ctx, &qbe_word, ".%d");
+ struct qbe_value end_oob = mkqtmp(ctx, &qbe_word, ".%d");
+ struct qbe_value valid = mkqtmp(ctx, &qbe_word, ".%d");
+ pushi(ctx->current, &start_oob, Q_CULTL, &qstart, &qlength, NULL);
+ pushi(ctx->current, &end_oob, Q_CULEL, &qend, &qlength, NULL);
+ pushi(ctx->current, &valid, Q_AND, &start_oob, &end_oob, NULL);
+
+ struct qbe_statement linvalid, lvalid;
+ struct qbe_value binvalid = mklabel(ctx, &linvalid, ".%d");
+ struct qbe_value bvalid = mklabel(ctx, &lvalid, ".%d");
+
+ pushi(ctx->current, NULL, Q_JNZ, &valid, &bvalid, &binvalid, NULL);
+ push(&ctx->current->body, &linvalid);
+ gen_fixed_abort(ctx, expr->loc, ABORT_OOB);
+ push(&ctx->current->body, &lvalid);
+
struct qbe_value isz = constl(srctype->array.members->size);
struct qbe_value qout = mkqval(ctx, &out);