harec

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

commit 1e2b6a1c399039c995448b35543a0bb0d31095d5
parent a8f7752df0f0c42e2311ec85240dde16491d808b
Author: Drew DeVault <sir@cmpwn.com>
Date:   Tue,  2 Feb 2021 21:36:18 -0500

gen: implement freeing strings

Diffstat:
Msrc/gen.c | 16+++++++++++-----
Mtests/17-alloc.ha | 11+++++++++++
2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -563,6 +563,7 @@ gen_expr_alloc(struct gen_context *ctx, { assert(expr->type == EXPR_ALLOC); struct qbe_value val = {0}, rtfunc = {0}; + const struct type *type = type_dealias(expr->alloc.expr->result); switch (expr->alloc.kind) { case AKIND_ALLOC: gen_alloc(ctx, expr, out); @@ -570,15 +571,17 @@ gen_expr_alloc(struct gen_context *ctx, case AKIND_APPEND: assert(0); // TODO case AKIND_FREE: - gen_temp(ctx, &val, - qtype_for_type(ctx, expr->alloc.expr->result, true), - "free.%d"); - if (type_dealias(expr->alloc.expr->result)->storage == TYPE_STORAGE_SLICE) { - qval_address(&val); + if (type->storage == TYPE_STORAGE_SLICE + || type->storage == TYPE_STORAGE_STRING) { + alloc_temp(ctx, &val, type, "free.%d"); + val.type = &qbe_long; gen_expression(ctx, expr->alloc.expr, &val); val.type = &qbe_long; pushi(ctx->current, &val, Q_LOADL, &val, NULL); } else { + gen_temp(ctx, &val, + qtype_for_type(ctx, expr->alloc.expr->result, false), + "free.%d"); gen_expression(ctx, expr->alloc.expr, &val); } rtfunc.kind = QV_GLOBAL; @@ -2383,6 +2386,9 @@ gen_data_item(struct gen_context *ctx, struct expression *expr, for (struct struct_constant *f = constant->_struct; f; f = f->next) { gen_data_item(ctx, f->value, item); + while (item->next) { + item = item->next; + } if (f->next) { const struct struct_field *f1 = f->field; const struct struct_field *f2 = f->next->field; diff --git a/tests/17-alloc.ha b/tests/17-alloc.ha @@ -60,6 +60,17 @@ fn slice() void = { free(x); }; +fn string() void = { + let x = struct { + data: *[3]int = alloc(*[3]int, [1, 2, 3]), + length: size = 3z, + capacity: size = 3z, + }; + let y = *(&x: *str); + assert(len(y) == 3z); + free(y); +}; + export fn main() void = { assignment(); allocation();