harec

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

commit 74650bc728a53268192bc9794c5ac9a78da12215
parent 15d37ce99f3d0f0822b3bb69c1cbcf1c4b4a42a6
Author: Drew DeVault <sir@cmpwn.com>
Date:   Tue,  2 Feb 2021 11:49:26 -0500

check: lower casts to tagged intermediates

Diffstat:
Msrc/check.c | 9+++++++++
Msrc/gen.c | 7++++---
2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/check.c b/src/check.c @@ -45,6 +45,15 @@ lower_implicit_cast(const struct type *to, struct expression *expr) if (to == expr->result) { return expr; } + + if (type_dealias(to)->storage == TYPE_STORAGE_TAGGED) { + const struct type *interim = + tagged_select_subtype(to, expr->result); + if (interim) { + expr = lower_implicit_cast(interim, expr); + } + } + struct expression *cast = xcalloc(1, sizeof(struct expression)); cast->type = EXPR_CAST; cast->result = to; diff --git a/src/gen.c b/src/gen.c @@ -881,19 +881,20 @@ gen_cast_to_tagged(struct gen_context *ctx, const struct type *subtype = tagged_select_subtype(tagged, from); struct qbe_value tag = {0}, ptr = {0}, offs = {0}; - gen_temp(ctx, &ptr, &qbe_long, "to_tagged.from.%d"); constl(&offs, expr->result->align); if (!subtype) { pushc(ctx->current, "to_tagged; no subtype"); + alloc_temp(ctx, &ptr, tagged, "to_tagged.from.%d"); + qval_deref(&ptr); gen_expression(ctx, expr->cast.value, &ptr); gen_copy(ctx, out, &ptr); return; } + gen_temp(ctx, &ptr, &qbe_long, "to_tagged.from.%d"); pushc(ctx->current, "to_tagged; valid subtype"); - // TODO: check should lower this to multiple casts: - assert(subtype->id == from->id); + assert(subtype->id == from->id); // Lowered by check if (out) { constw(&tag, subtype->id);