commit 14b8916bf93f17d3d2402981021a445c6dc3e111
parent db0bfa1523aea9f3727d5bd3e8eb11b9395befc3
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 9 Aug 2021 11:07:04 +0200
gen: skip bounds test on [*]type
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
M | src/gen.c | | | 31 | ++++++++++++++++++------------- |
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/src/gen.c b/src/gen.c
@@ -240,10 +240,11 @@ gen_access_index(struct gen_context *ctx, const struct expression *expr)
glval = gen_autoderef(ctx, glval);
struct qbe_value qlval = mkqval(ctx, &glval);
struct qbe_value qival = mkqtmp(ctx, ctx->arch.ptr, ".%d");
+ bool checkbounds = true;
struct qbe_value length;
const struct type *ty = type_dealias(glval.type);
switch (ty->storage) {
- case STORAGE_SLICE: {
+ case STORAGE_SLICE:;
enum qbe_instr load = load_for_type(ctx, &builtin_type_size);
struct qbe_value base = mkqtmp(ctx, ctx->arch.ptr, ".%d");
pushi(ctx->current, &base, load, &qlval, NULL);
@@ -256,10 +257,12 @@ gen_access_index(struct gen_context *ctx, const struct expression *expr)
qlval = base;
break;
- }
case STORAGE_ARRAY:
- assert(ty->array.length != SIZE_UNDEFINED);
- length = constl(ty->array.length);
+ if (ty->array.length != SIZE_UNDEFINED) {
+ length = constl(ty->array.length);
+ } else {
+ checkbounds = false;
+ }
break;
default:
assert(0); // Unreachable
@@ -271,17 +274,19 @@ gen_access_index(struct gen_context *ctx, const struct expression *expr)
pushi(ctx->current, &qival, Q_MUL, &qindex, &itemsz, NULL);
pushi(ctx->current, &qival, Q_ADD, &qlval, &qival, NULL);
- struct qbe_value valid = mkqtmp(ctx, &qbe_word, ".%d");
- pushi(ctx->current, &valid, Q_CULTL, &qindex, &length, NULL);
+ if (checkbounds) {
+ struct qbe_value valid = mkqtmp(ctx, &qbe_word, ".%d");
+ pushi(ctx->current, &valid, Q_CULTL, &qindex, &length, NULL);
- struct qbe_statement linvalid, lvalid;
- struct qbe_value binvalid = mklabel(ctx, &linvalid, ".%d");
- struct qbe_value bvalid = mklabel(ctx, &lvalid, ".%d");
+ 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);
+ 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);
+ }
return (struct gen_value){
.kind = GV_TEMP,