harec

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

commit 653893e58f142313ed264ddbad3a00bdd01af180
parent c53e5860b44a3837d74b59c7f08586f7aa52acd4
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Mon,  6 Sep 2021 08:47:08 +0000

check: binarithm: disallow invalid result types

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

Diffstat:
Msrc/check.c | 66+++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 53 insertions(+), 13 deletions(-)

diff --git a/src/check.c b/src/check.c @@ -690,7 +690,12 @@ check_expr_binarithm(struct context *ctx, expr->type = EXPR_BINARITHM; expr->binarithm.op = aexpr->binarithm.op; - bool numeric; + enum { + BT_NUMERIC, + BT_LOGICAL, + BT_COMPARISON, + BT_EQUALITY, + } btype; switch (expr->binarithm.op) { // Numeric arithmetic case BIN_BAND: @@ -703,19 +708,25 @@ check_expr_binarithm(struct context *ctx, case BIN_RSHIFT: case BIN_TIMES: case BIN_BXOR: - numeric = true; + btype = BT_NUMERIC; break; // Logical arithmetic + case BIN_LAND: + case BIN_LOR: + case BIN_LXOR: + btype = BT_LOGICAL; + hint = NULL; + break; case BIN_GREATER: case BIN_GREATEREQ: - case BIN_LAND: - case BIN_LEQUAL: case BIN_LESS: case BIN_LESSEQ: - case BIN_LOR: - case BIN_LXOR: + btype = BT_COMPARISON; + hint = NULL; + break; + case BIN_LEQUAL: case BIN_NEQUAL: - numeric = false; + btype = BT_EQUALITY; hint = NULL; break; } @@ -778,17 +789,46 @@ check_expr_binarithm(struct context *ctx, "Cannot promote lvalue and rvalue"); return; } + expr->result = &builtin_type_bool; + switch (btype) { + case BT_NUMERIC: + if (!type_is_numeric(p)) { + error(ctx, aexpr->loc, expr, + "Cannot perform arithmetic on non-numeric %s type", + type_storage_unparse(type_dealias(p)->storage)); + } + expr->result = p; + break; + case BT_LOGICAL: + if (type_dealias(p)->storage != STORAGE_BOOL) { + error(ctx, aexpr->loc, expr, + "Cannot perform logical arithmetic on non-bool %s type", + type_storage_unparse(type_dealias(p)->storage)); + } + break; + case BT_COMPARISON: + if (!type_is_numeric(p)) { + error(ctx, aexpr->loc, expr, + "Cannot perform comparison on non-numeric %s type", + type_storage_unparse(type_dealias(p)->storage)); + } + break; + case BT_EQUALITY: + if (!type_is_numeric(p) && type_dealias(p)->storage != STORAGE_POINTER + && type_dealias(p)->storage != STORAGE_STRING + && type_dealias(p)->storage != STORAGE_BOOL + && type_dealias(p)->storage != STORAGE_RUNE) { + error(ctx, aexpr->loc, expr, + "Cannot perform equality test on %s type", + type_storage_unparse(type_dealias(p)->storage)); + } + break; + } lvalue = lower_implicit_cast(p, lvalue); rvalue = lower_implicit_cast(p, rvalue); expr->binarithm.lvalue = lvalue; expr->binarithm.rvalue = rvalue; - - if (numeric) { - expr->result = p; - } else { - expr->result = &builtin_type_bool; - } } static void