From a2f02b8b3218dc83a2a2783ceb79cc57abacc7bd Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 21 Feb 2023 16:31:22 +0000 Subject: [PATCH] Fix bug with for in statements and pointer intervals --- src/check_expr.cpp | 20 ++++++++++++++------ src/check_stmt.cpp | 4 ++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 2ed77535c..8a3bb2c1b 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -7040,7 +7040,7 @@ gb_internal bool ternary_compare_types(Type *x, Type *y) { } -gb_internal bool check_range(CheckerContext *c, Ast *node, Operand *x, Operand *y, ExactValue *inline_for_depth_, Type *type_hint=nullptr) { +gb_internal bool check_range(CheckerContext *c, Ast *node, bool is_for_loop, Operand *x, Operand *y, ExactValue *inline_for_depth_, Type *type_hint=nullptr) { if (!is_ast_range(node)) { return false; } @@ -7089,9 +7089,17 @@ gb_internal bool check_range(CheckerContext *c, Ast *node, Operand *x, Operand * } 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"); - return false; + + if (is_for_loop) { + if (!is_type_integer(type) && !is_type_float(type) && !is_type_enum(type)) { + error(ie->op, "Only numerical types are allowed within interval expressions"); + return false; + } + } else { + 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"); + return false; + } } if (x->mode == Addressing_Constant && @@ -8104,7 +8112,7 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * Operand x = {}; Operand y = {}; - bool ok = check_range(c, fv->field, &x, &y, nullptr); + bool ok = check_range(c, fv->field, false, &x, &y, nullptr); if (!ok) { continue; } @@ -8320,7 +8328,7 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * Operand x = {}; Operand y = {}; - bool ok = check_range(c, fv->field, &x, &y, nullptr, index_type); + bool ok = check_range(c, fv->field, false, &x, &y, nullptr, index_type); if (!ok) { continue; } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 3039995b9..f300f45c7 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -725,7 +725,7 @@ gb_internal void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod Operand x = {}; Operand y = {}; - bool ok = check_range(ctx, expr, &x, &y, &inline_for_depth); + bool ok = check_range(ctx, expr, true, &x, &y, &inline_for_depth); if (!ok) { goto skip_expr; } @@ -1439,7 +1439,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) Operand x = {}; Operand y = {}; - bool ok = check_range(ctx, expr, &x, &y, nullptr); + bool ok = check_range(ctx, expr, true, &x, &y, nullptr); if (!ok) { goto skip_expr_range_stmt; }