harec

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

commit 22fb3cf780accc1e313e10035072198403f8f655
parent b4b40d5dab2f1555874df74cc59a63a89c538528
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Sat, 24 Apr 2021 14:07:05 -0400

Disallow errors when the type hint is void

Signed-off-by: Eyal Sawady <ecs@d2evs.net>

Diffstat:
Msrc/check.c | 36++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/src/check.c b/src/check.c @@ -1034,8 +1034,10 @@ check_expr_cast(struct context *ctx, xcalloc(1, sizeof(struct expression)); const struct type *secondary = expr->cast.secondary = type_store_lookup_atype(ctx->store, aexpr->cast.type); - errors = check_expression(ctx, aexpr->cast.value, value, secondary, - errors); + // TODO: Instead of allowing errors on casts to void, we should use a + // different nonterminal + errors = check_expression(ctx, aexpr->cast.value, value, + secondary == &builtin_type_void ? NULL : secondary, errors); if (aexpr->cast.kind == C_ASSERTION || aexpr->cast.kind == C_TEST) { const struct type *primary = type_dealias(expr->cast.value->result); @@ -1609,23 +1611,15 @@ check_expr_list(struct context *ctx, alist->next ? &builtin_type_void : hint, errors); list->expr = lexpr; - if (alist->next) { - expect(&alist->expr->loc, !type_has_error(lexpr->result), - "Cannot ignore error here"); + alist = alist->next; + if (alist) { *next = xcalloc(1, sizeof(struct expressions)); list = *next; next = &list->next; } else { - // XXX: This is a bit of a hack - if (hint && !type_has_error(hint)) { - expect(&alist->expr->loc, - !type_has_error(lexpr->result), - "Cannot ignore error here"); - } expr->result = lexpr->result; expr->terminates = lexpr->terminates; } - alist = alist->next; } scope_pop(&ctx->scope); @@ -2552,6 +2546,24 @@ check_expression(struct context *ctx, break; } assert(expr->result); + if (hint && hint->storage == STORAGE_VOID) { + if ((expr->result->flags & TYPE_ERROR) != 0) { + return error(aexpr->loc, expr, errors, + "Cannot assign error type to void"); + } + if (type_dealias(expr->result)->storage != STORAGE_TAGGED) { + return errors; + } + const struct type_tagged_union *tu = + &type_dealias(expr->result)->tagged; + for (; tu; tu = tu->next) { + if ((tu->type->flags & TYPE_ERROR) == 0) { + continue; + } + return error(aexpr->loc, expr, errors, + "Cannot assign error type to void"); + } + } return errors; }