harec

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

commit 8ffde0ac1457cb165a9fb8ab74fc967050932266
parent 760442a0e917c516282418074a9d584a1ff71df5
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Tue, 16 Feb 2021 20:04:02 -0500

gen: fix cast from zero-length array to slice

We need a null data field in this case instead of a pointer to the
original array.

Diffstat:
Msrc/gen.c | 8+++++++-
Mtests/08-slices.ha | 14+++++++++++---
2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -1383,7 +1383,13 @@ gen_expr_cast(struct gen_context *ctx, constl(&offs, 8); constl(&len, from->array.length); pushi(ctx->current, &ptr, Q_COPY, out, NULL); - pushi(ctx->current, NULL, Q_STOREL, &in, &ptr, NULL); + if (from->array.length == 0) { + struct qbe_value temp = {0}; + constl(&temp, 0); + pushi(ctx->current, NULL, Q_STOREL, &temp, &ptr, NULL); + } else { + pushi(ctx->current, NULL, Q_STOREL, &in, &ptr, NULL); + } pushi(ctx->current, &ptr, Q_ADD, &ptr, &offs, NULL); pushi(ctx->current, NULL, Q_STOREL, &len, &ptr, NULL); pushi(ctx->current, &ptr, Q_ADD, &ptr, &offs, NULL); diff --git a/tests/08-slices.ha b/tests/08-slices.ha @@ -3,12 +3,20 @@ use rt; fn from_array() void = { let src = [1, 2, 3]; let x: []int = src; - let ptr = &x: *struct { - data: *[*]int, + let xptr = &x: *struct { + data: nullable *[*]int, + length: size, + capacity: size, + }; + assert(xptr.data == &src); + + let y: []int = []; + let yptr = &y: *struct { + data: nullable *[*]int, length: size, capacity: size, }; - assert(ptr.data == &src); + assert(yptr.data == null); }; fn storage() void = {