harec

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

commit a34531174c345e658267fa8f7bc7bdc0035c0c36
parent ec59e8c5881a3b4c68e9c7d023f11f18c40d83cc
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun, 24 Jan 2021 11:13:32 -0500

gen: fix isssues with aggregate types in return

Diffstat:
Msrc/emit.c | 14++++++++++----
Msrc/gen.c | 31+++++++++++++++++++++++--------
2 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/src/emit.c b/src/emit.c @@ -137,16 +137,22 @@ emit_stmt(struct qbe_statement *stmt, FILE *out) break; case Q_INSTR: fprintf(out, "\t"); + if (stmt->instr == Q_CALL) { + if (stmt->out != NULL) { + emit_value(stmt->out, out); + fprintf(out, " ="); + emit_qtype(stmt->out->type, true, out); + fprintf(out, " "); + } + emit_call(stmt, out); + break; + } if (stmt->out != NULL) { emit_value(stmt->out, out); fprintf(out, " ="); emit_qtype(stmt->out->type, false, out); fprintf(out, " "); } - if (stmt->instr == Q_CALL) { - emit_call(stmt, out); - break; - } fprintf(out, "%s%s", qbe_instr[stmt->instr], stmt->args ? " " : ""); struct qbe_arguments *arg = stmt->args; diff --git a/src/gen.c b/src/gen.c @@ -623,6 +623,8 @@ gen_expr_assign(struct gen_context *ctx, } else { const struct expression *object = expr->assign.object; address_object(ctx, object, &src); + pushc(ctx->current, "assign to object %s (%c)", + src.name, (char)src.type->stype); } const struct expression *value = expr->assign.value; @@ -990,6 +992,11 @@ gen_expr_cast(struct gen_context *ctx, return; } + if (to->storage == TYPE_STORAGE_VOID) { + gen_expression(ctx, expr->cast.value, NULL); + return; + } + if (type_is_aggregate(expr->cast.value->result) && expr->cast.value->type == EXPR_CONSTANT) { // This is a stupid fucking hack @@ -1987,6 +1994,9 @@ gen_function_decl(struct gen_context *ctx, const struct declaration *decl) struct qbe_value rval = {0}; if (fntype->func.result->storage != TYPE_STORAGE_VOID) { alloc_temp(ctx, &rval, fntype->func.result, "ret.%d"); + if (type_is_aggregate(fntype->func.result)) { + rval.indirect = false; + } ctx->return_value = &rval; } else { ctx->return_value = NULL; @@ -2000,11 +2010,15 @@ gen_function_decl(struct gen_context *ctx, const struct declaration *decl) pop_scope(ctx); if (fntype->func.result->storage != TYPE_STORAGE_VOID) { - struct qbe_value load = {0}; - gen_loadtemp(ctx, &load, ctx->return_value, - qdef->func.returns, - type_is_signed(fntype->func.result)); - pushi(&qdef->func, NULL, Q_RET, &load, NULL); + if (type_is_aggregate(fntype->func.result)) { + pushi(&qdef->func, NULL, Q_RET, ctx->return_value, NULL); + } else { + struct qbe_value load = {0}; + gen_loadtemp(ctx, &load, ctx->return_value, + qdef->func.returns, + type_is_signed(fntype->func.result)); + pushi(&qdef->func, NULL, Q_RET, &load, NULL); + } } else { pushi(&qdef->func, NULL, Q_RET, NULL); } @@ -2105,10 +2119,11 @@ gen_data_item(struct gen_context *ctx, struct expression *expr, break; case TYPE_STORAGE_ARRAY: assert(type->array.length != SIZE_UNDEFINED); - assert(!constant->array->expand); // TODO - for (struct array_constant *c = constant->array; c; c = c->next) { + size_t n = type->array.length; + for (struct array_constant *c = constant->array; + c && n; c = c->next ? c->next : c, --n) { gen_data_item(ctx, c->value, item); - if (c->next) { + if (n > 1 || c->next) { item->next = xcalloc(1, sizeof(struct qbe_data_item)); item = item->next;