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:
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 = ¬
+ let g = &f;
+ assert(not(true) == false);
+ assert(f(true) == false);
+ assert(g(true) == false);
return 0;
};