commit 9aa447a7047b249c7649abfc339841e28525c765
parent 87f934c68d3cb6a24aaa6cdc0f9cf1a5a5981992
Author: Eyal Sawady <ecs@d2evs.net>
Date: Fri, 5 Feb 2021 12:16:59 -0500
check: implement if with tagged union result
Diffstat:
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/src/check.c b/src/check.c
@@ -941,11 +941,21 @@ check_expr_if(struct context *ctx,
expr->result = false_branch->result;
} else if (false_branch->terminates) {
expr->result = true_branch->result;
- } else {
- // TODO: Tagged unions
- assert(true_branch->result == false_branch->result);
+ } else if (true_branch->result == false_branch->result) {
expr->result = true_branch->result;
+ } else {
+ struct type_tagged_union _tags = {
+ .type = false_branch->result,
+ .next = NULL,
+ }, tags = {
+ .type = true_branch->result,
+ .next = &_tags,
+ };
+ expr->result =
+ type_store_lookup_tagged(ctx->store, &tags);
}
+ true_branch = lower_implicit_cast(expr->result, true_branch);
+ false_branch = lower_implicit_cast(expr->result, false_branch);
} else {
expr->result = &builtin_type_void;
expr->terminates = true_branch->terminates;
diff --git a/src/gen.c b/src/gen.c
@@ -1082,7 +1082,7 @@ gen_expr_type_assertion(struct gen_context *ctx,
*tagged = type_dealias(expr->cast.value->result);
struct qbe_value tag = {0}, in = {0}, id = {0}, result = {0};
gen_temp(ctx, &tag, &qbe_word, "tag.%d");
- gen_temp(ctx, &in, qtype_for_type(ctx, tagged, false), "cast.in.%d");
+ alloc_temp(ctx, &in, tagged, "cast.in.%d");
qval_address(&in);
gen_expression(ctx, expr->cast.value, &in);
pushi(ctx->current, &tag, Q_LOADUW, &in, NULL);