harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 1730c7d71a8865c5cdca4752c255c9d65bc674f7
parent ed6140b383e8f9824912b7d7b9bbb38ab8b0e377
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun, 24 Jan 2021 12:05:21 -0500

gen: fix slicing pointers to objects

Diffstat:
Msrc/check.c | 7+++----
Msrc/gen.c | 14+++++++++++---
Mtests/08-slices.ha | 6++++++
3 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/src/check.c b/src/check.c @@ -1050,8 +1050,8 @@ check_expr_slice(struct context *ctx, expect(&aexpr->slice.object->loc, atype, "Cannot dereference nullable pointer for slicing"); expect(&aexpr->slice.object->loc, - expr->slice.object->result->storage == TYPE_STORAGE_SLICE || - expr->slice.object->result->storage == TYPE_STORAGE_ARRAY, + atype->storage == TYPE_STORAGE_SLICE + || atype->storage == TYPE_STORAGE_ARRAY, "Cannot slice non-array, non-slice object"); const struct type *itype; @@ -1079,8 +1079,7 @@ check_expr_slice(struct context *ctx, // TODO: Assert that array type has a well-defined length } - expr->result = type_store_lookup_slice(ctx->store, - expr->slice.object->result->array.members); + expr->result = type_store_lookup_slice(ctx->store, atype->array.members); trleave(TR_CHECK, NULL); } diff --git a/src/gen.c b/src/gen.c @@ -1653,13 +1653,21 @@ gen_expr_slice(struct gen_context *ctx, const struct qbe_value *out) { // XXX: ARCH - struct qbe_value object = {0}, start = {0}, end = {0}; + struct qbe_value object = {0}, start = {0}, end = {0}, temp = {0}; const struct type *otype = expr->slice.object->result; - address_object(ctx, expr->slice.object, &object); + address_object(ctx, expr->slice.object, &temp); + gen_temp(ctx, &object, object.type, "object.%d"); + object.type = temp.type; + pushi(ctx->current, &object, Q_COPY, &temp, NULL); + while (otype->storage == TYPE_STORAGE_POINTER) { + pushi(ctx->current, &object, Q_LOADL, &object, NULL); + otype = type_dereference(otype->pointer.referent); + } + gen_temp(ctx, &start, &qbe_long, "start.%d"); gen_temp(ctx, &end, &qbe_long, "end.%d"); - struct qbe_value src = {0}, dest = {0}, temp = {0}, offset = {0}; + struct qbe_value src = {0}, dest = {0}, offset = {0}; gen_temp(ctx, &dest, &qbe_long, "dest.%d"); gen_temp(ctx, &offset, &qbe_long, "offset.%d"); diff --git a/tests/08-slices.ha b/tests/08-slices.ha @@ -83,6 +83,12 @@ fn slicing() void = { assert_slice_eq(b[..3], [1, 2, 3]); assert_slice_eq(b[1..3], [2, 3]); assert_slice_eq(b[1..], [2, 3, 4, 5]); + + let p = &a; + assert_slice_eq(p[..], [1, 2, 3, 4, 5]); + assert_slice_eq(p[..3], [1, 2, 3]); + assert_slice_eq(p[1..3], [2, 3]); + assert_slice_eq(p[1..], [2, 3, 4, 5]); assert(rt::compile( "fn test() void = { let x = \"test\"; x[1..3]; };"