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:
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 = {