commit f89dd7c11cb28821d40d8081f0806b979b723d79
parent 5b2bea4b8b7a9176c560fef287b5493ff70b68b7
Author: Eyal Sawady <ecs@d2evs.net>
Date: Fri, 13 Aug 2021 09:15:32 +0000
insert: implement auto-deref
Signed-off-by: Eyal Sawady <ecs@d2evs.net>
Diffstat:
3 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/src/check.c b/src/check.c
@@ -1651,12 +1651,17 @@ check_expr_insert(struct context *ctx,
assert(expr->insert.expr->type == EXPR_ACCESS
&& expr->insert.expr->access.type == ACCESS_INDEX);
const struct type *sltype = expr->insert.expr->access.array->result;
- if (type_dealias(sltype)->storage != STORAGE_SLICE) {
+ sltype = type_dereference(sltype);
+ if (!sltype) {
+ return error(aexpr->access.array->loc, expr, errors,
+ "Cannot dereference nullable pointer for insert");
+ }
+ if (sltype->storage != STORAGE_SLICE) {
return error(aexpr->insert.expr->loc, expr, errors,
"cannot insert into non-slice type %s",
type_storage_unparse(type_dealias(sltype)->storage));
}
- if (type_dealias(sltype)->flags & TYPE_CONST) {
+ if (sltype->flags & TYPE_CONST) {
return error(aexpr->insert.expr->loc, expr, errors,
"insert must operate on a mutable slice");
}
diff --git a/src/gen.c b/src/gen.c
@@ -1669,11 +1669,12 @@ gen_expr_insert(struct gen_context *ctx, const struct expression *expr)
&& objexpr->access.type == ACCESS_INDEX);
const struct expression *arrayexpr = objexpr->access.array;
- struct gen_value slice = gen_expr_access_addr(ctx, arrayexpr);
+ struct gen_value slice = gen_expr(ctx, arrayexpr);
+ slice = gen_autoderef(ctx, slice);
struct gen_value index = gen_expr(ctx, objexpr->access.index);
struct qbe_value qindex = mkqval(ctx, &index);
- const struct type *sltype = type_dealias(arrayexpr->result);
+ const struct type *sltype = type_dereference(arrayexpr->result);
const struct type *mtype = type_dealias(sltype)->array.members;
enum qbe_instr load = load_for_type(ctx, &builtin_type_size);
diff --git a/tests/28-insert.ha b/tests/28-insert.ha
@@ -20,7 +20,8 @@ fn basics() void = {
let x: []int = alloc([], 9);
defer free(x);
append(x, 1, 2, 3, 4, 5, 6);
- insert(x[2], 7, 8, 9);
+ let y = &x;
+ insert(y[2], 7, 8, 9);
assert(sleq(x, [1, 2, 7, 8, 9, 3, 4, 5, 6]));
};
@@ -33,8 +34,10 @@ fn variadic() void = {
let x: []int = [];
defer free(x);
- append(x, 1, 2, 3, 4, 5, 6);
- insert(x[2], 7, 8, 9, [10, 11, 12]...);
+ let y = &x;
+ let z = &y;
+ append(y, 1, 2, 3, 4, 5, 6);
+ insert(z[2], 7, 8, 9, [10, 11, 12]...);
assert(sleq(x, [1, 2, 7, 8, 9, 10, 11, 12, 3, 4, 5, 6]));
};