diff --git a/src/check_expr.cpp b/src/check_expr.cpp index fae38fa01..ef43812c0 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -6739,7 +6739,7 @@ bool check_range(CheckerContext *c, Ast *node, Operand *x, Operand *y, ExactValu } if (inline_for_depth_) *inline_for_depth_ = inline_for_depth; - } else { + } else if (inline_for_depth_ != nullptr) { error(ie->op, "Interval expressions must be constant"); return false; } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index d4398664b..2bf82facd 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1476,80 +1476,14 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { if (is_ast_range(expr)) { ast_node(ie, BinaryExpr, expr); - Operand x = {Addressing_Invalid}; - Operand y = {Addressing_Invalid}; + Operand x = {}; + Operand y = {}; - check_expr(ctx, &x, ie->left); - if (x.mode == Addressing_Invalid) { + bool ok = check_range(ctx, expr, &x, &y, nullptr); + if (!ok) { goto skip_expr_range_stmt; } - check_expr(ctx, &y, ie->right); - if (y.mode == Addressing_Invalid) { - goto skip_expr_range_stmt; - } - - convert_to_typed(ctx, &x, y.type); - if (x.mode == Addressing_Invalid) { - goto skip_expr_range_stmt; - } - convert_to_typed(ctx, &y, x.type); - if (y.mode == Addressing_Invalid) { - goto skip_expr_range_stmt; - } - - convert_to_typed(ctx, &x, default_type(y.type)); - if (x.mode == Addressing_Invalid) { - goto skip_expr_range_stmt; - } - convert_to_typed(ctx, &y, default_type(x.type)); - if (y.mode == Addressing_Invalid) { - goto skip_expr_range_stmt; - } - - if (!are_types_identical(x.type, y.type)) { - if (x.type != t_invalid && - y.type != t_invalid) { - gbString xt = type_to_string(x.type); - gbString yt = type_to_string(y.type); - gbString expr_str = expr_to_string(x.expr); - error(ie->op, "Mismatched types in interval expression '%s' : '%s' vs '%s'", expr_str, xt, yt); - gb_string_free(expr_str); - gb_string_free(yt); - gb_string_free(xt); - } - goto skip_expr_range_stmt; - } - - Type *type = x.type; - if (!is_type_integer(type) && !is_type_float(type) && !is_type_pointer(type) && !is_type_enum(type)) { - error(ie->op, "Only numerical and pointer types are allowed within interval expressions"); - goto skip_expr_range_stmt; - } - - if (x.mode == Addressing_Constant && - y.mode == Addressing_Constant) { - ExactValue a = x.value; - ExactValue b = y.value; - - GB_ASSERT(are_types_identical(x.type, y.type)); - - TokenKind op = Token_Lt; - switch (ie->op.kind) { - case Token_Ellipsis: op = Token_LtEq; break; - case Token_RangeHalf: op = Token_Lt; break; - default: error(ie->op, "Invalid range operator"); break; - } - bool ok = compare_exact_values(op, a, b); - if (!ok) { - // TODO(bill): Better error message - error(ie->op, "Invalid interval range"); - goto skip_expr_range_stmt; - } - } - - add_type_and_value(&ctx->checker->info, ie->left, x.mode, x.type, x.value); - add_type_and_value(&ctx->checker->info, ie->right, y.mode, y.type, y.value); - val0 = type; + val0 = x.type; val1 = t_int; } else { Operand operand = {Addressing_Invalid}; diff --git a/src/checker.cpp b/src/checker.cpp index 4490caa69..8ba45a799 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1033,7 +1033,9 @@ void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *ty expr->tav.mode = mode; expr->tav.type = type; - expr->tav.value = value; + if (mode == Addressing_Constant || mode == Addressing_Invalid) { + expr->tav.value = value; + } } void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity *entity) { diff --git a/src/ir.cpp b/src/ir.cpp index 8d5587341..d7db09180 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -6613,22 +6613,6 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) { GB_ASSERT(tv.mode != Addressing_Invalid); GB_ASSERT(tv.mode != Addressing_Type); - #if 0 - if (tv.mode == Addressing_Type) { - // // TODO(bill): Handle this correctly - #if 0 - i32 entry_index = ir_type_info_index(proc->module->info, tv.type, false); - if (entry_index >= 0) { - return ir_get_type_info_ptr(proc, tv.type); - // i32 id = entry_index+1; - // return ir_value_constant(t_int, exact_value_i64(id)); - } - #endif - // return v_raw_nil; - return ir_value_nil(tv.type); - } - #endif - if (tv.value.kind != ExactValue_Invalid) { // NOTE(bill): Edge case if (tv.value.kind != ExactValue_Compound && @@ -8686,7 +8670,8 @@ void ir_build_range_interval(irProcedure *proc, AstBinaryExpr *node, Type *val_t upper = ir_build_expr(proc, node->right); - irValue *cond = ir_emit_comp(proc, op, ir_emit_load(proc, value), upper); + irValue *curr_value = ir_emit_load(proc, value); + irValue *cond = ir_emit_comp(proc, op, curr_value, upper); ir_emit_if(proc, cond, body, done); ir_start_block(proc, body);