commit 8befc456247c9203a36234add1f6016e6ffc260c
parent eb1be33c198bbf3ff042651d95895d83a28987a5
Author: Ember Sawady <ecs@d2evs.net>
Date: Mon, 19 Dec 2022 21:49:01 +0000
Implement object addresses in gen_expr_const
Fixes switches on addresses of globals
Signed-off-by: Ember Sawady <ecs@d2evs.net>
Diffstat:
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/src/gen.c b/src/gen.c
@@ -205,9 +205,8 @@ gen_autoderef(struct gen_context *ctx, struct gen_value val)
}
static struct gen_value
-gen_access_ident(struct gen_context *ctx, const struct expression *expr)
+gen_access_ident(struct gen_context *ctx, const struct scope_object *obj)
{
- const struct scope_object *obj = expr->access.object;
switch (obj->otype) {
case O_BIND:
for (const struct gen_binding *gb = ctx->bindings;
@@ -334,7 +333,7 @@ gen_expr_access_addr(struct gen_context *ctx, const struct expression *expr)
struct gen_value addr;
switch (expr->access.type) {
case ACCESS_IDENTIFIER:
- addr = gen_access_ident(ctx, expr);
+ addr = gen_access_ident(ctx, expr->access.object);
break;
case ACCESS_INDEX:
addr = gen_access_index(ctx, expr);
@@ -2032,6 +2031,13 @@ gen_expr_const(struct gen_context *ctx, const struct expression *expr)
break;
}
+ if (expr->constant.object != NULL) {
+ assert(expr->constant.ival == 0);
+ val = gen_access_ident(ctx, expr->constant.object);
+ val.type = expr->result;
+ return val;
+ }
+
const struct qbe_type *qtype = qtype_lookup(ctx, expr->result, false);
switch (qtype->stype) {
case Q_BYTE:
diff --git a/tests/26-gen.ha b/tests/26-gen.ha
@@ -18,6 +18,8 @@ def THING: thing = thing{
},
};
+let global: int = 0;
+
export fn main() void = {
let t = thing {
offs = 0,
@@ -62,4 +64,9 @@ export fn main() void = {
yield p;
};
*p = 0;
+
+ switch (&global) {
+ case &global => void;
+ case => abort();
+ };
};