harec

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

commit c29a0ce2e3120db8f5df9b5ba3929aa26feb1ac3
parent 95b6e1019874a413473a68426f5c340aef67dc68
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 24 Jul 2021 14:24:32 +0200

gen: expand deref tests, fix call issue

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Msrc/gen.c | 6++++--
Msrc/genutil.c | 2+-
Mtests/904-deref.ha | 15++++++++++++++-
3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -12,6 +12,10 @@ static void gen_auto_deref(struct gen_context *ctx, struct gen_temp *val) { const struct type *type = val->type; + if (!val->indirect && type_dealias(type)->storage == STORAGE_POINTER) { + // We get one free dereference in this case + type = type_dealias(type)->pointer.referent; + } struct qbe_value qval = {0}; qval_temp(ctx, &qval, val); while (type_dealias(type)->storage == STORAGE_POINTER) { @@ -218,8 +222,6 @@ gen_address_field(struct gen_context *ctx, struct gen_temp *temp, const struct expression *object = access->_struct; assert(object->type == EXPR_ACCESS); // TODO: Other cases? - pushc(ctx->current, "XXX"); - struct gen_temp base = {0}; struct qbe_value qbase = {0}, field = {0}, offset = {0}; gen_access_address(ctx, &base, object); diff --git a/src/genutil.c b/src/genutil.c @@ -147,7 +147,7 @@ void temp_address(struct gen_temp *temp, const struct type *type) { assert(type_dealias(type)->storage == STORAGE_POINTER); - assert(temp->indirect); + assert(temp->indirect || temp->is_global); temp->indirect = false; temp->type = type; } diff --git a/tests/904-deref.ha b/tests/904-deref.ha @@ -1,4 +1,6 @@ -type coords = struct { x: int, y: int }; +type coords = struct { x: size, y: size }; + +fn not(x: bool) bool = x == false; export fn main() int = { let a = coords { x = 10, y = 20 }; @@ -14,5 +16,16 @@ export fn main() int = { assert(x[2] == 3); assert(y[2] == 3); assert(z[2] == 3); + + let q = coords { x = 2, y = 2 }; + let o = &q; + assert(x[q.x] == 3); + assert(x[o.x] == 3); + + let f = &not; + let g = &f; + assert(not(true) == false); + assert(f(true) == false); + assert(g(true) == false); return 0; };