commit 1aa3c60e6e7966c322a84f152beb7b905455009a
parent 309af874ba591d9071f7a7bf55827349938c2578
Author: Eyal Sawady <ecs@d2evs.net>
Date: Sun, 21 Feb 2021 18:06:17 -0500
Fix len and append on aliases of slice types
Diffstat:
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/src/check.c b/src/check.c
@@ -236,17 +236,18 @@ check_expr_append(struct context *ctx,
expr->append.expr = xcalloc(sizeof(struct expression), 1);
check_expression(ctx, aexpr->append.expr, expr->append.expr, NULL);
expect(&aexpr->append.expr->loc,
- expr->append.expr->result->storage == STORAGE_SLICE,
+ type_dealias(expr->append.expr->result)->storage == STORAGE_SLICE,
"append must operate on a slice");
expect(&aexpr->append.expr->loc,
- !(expr->append.expr->result->flags & TYPE_CONST),
+ !(type_dealias(expr->append.expr->result)->flags & TYPE_CONST),
"append must operate on a mutable slice");
expect(&aexpr->append.expr->loc,
expr->append.expr->type == EXPR_ACCESS
|| (expr->append.expr->type == EXPR_UNARITHM
&& expr->append.expr->unarithm.op == UN_DEREF),
"append must operate on a slice object");
- const struct type *memb = expr->append.expr->result->array.members;
+ const struct type *memb =
+ type_dealias(expr->append.expr->result)->array.members;
struct append_values **next = &expr->append.values;
for (struct ast_append_values *avalue = aexpr->append.values; avalue;
avalue = avalue->next) {
@@ -1489,7 +1490,8 @@ check_expr_measure(struct context *ctx,
expr->measure.value = xcalloc(1, sizeof(struct expression));
check_expression(ctx, aexpr->measure.value,
expr->measure.value, NULL);
- enum type_storage vstor = expr->measure.value->result->storage;
+ enum type_storage vstor =
+ type_dealias(expr->measure.value->result)->storage;
expect(&aexpr->measure.value->loc,
vstor == STORAGE_ARRAY
|| vstor == STORAGE_SLICE
diff --git a/src/gen.c b/src/gen.c
@@ -659,16 +659,18 @@ gen_expr_append(struct gen_context *ctx,
}
gen_store(ctx, &lenptr, &newlen);
+ const struct type *mtype =
+ type_dealias(expr->append.expr->result)->array.members;
+
struct qbe_value rtfunc = {0}, membsz = {0};
- constl(&membsz, expr->append.expr->result->array.members->size);
+ constl(&membsz, mtype->size);
rtfunc.kind = QV_GLOBAL;
rtfunc.name = strdup("rt.ensure");
rtfunc.type = &qbe_long;
pushi(ctx->current, NULL, Q_CALL, &rtfunc, &val, &membsz, &newlen, NULL);
struct qbe_value ptr = {0};
- const struct qbe_type *type =
- qtype_for_type(ctx, expr->append.expr->result->array.members, false);
+ const struct qbe_type *type = qtype_for_type(ctx, mtype, false);
qval_deref(&val);
gen_loadtemp(ctx, &ptr, &val, &qbe_long, "append.ptr.%d");
qval_address(&ptr);
@@ -2061,7 +2063,7 @@ gen_expr_measure(struct gen_context *ctx,
struct qbe_value src = {0}, temp = {0}, ptr = {0};
switch (expr->measure.op) {
case M_LEN:
- switch (expr->measure.value->result->storage) {
+ switch (type_dealias(expr->measure.value->result)->storage) {
case STORAGE_ARRAY:
gen_temp(ctx, &temp,
qtype_for_type(ctx, expr->result, false),