aboutsummaryrefslogtreecommitdiff
path: root/src/check_stmt.cpp
diff options
context:
space:
mode:
authorKarl Zylinski <karl@zylinski.se>2024-09-17 19:36:17 +0200
committerKarl Zylinski <karl@zylinski.se>2024-09-17 19:36:17 +0200
commit093ade050445b3e348177e30fb1fc9d726f7b289 (patch)
tree5122cfefa5fefbab9d27d5d8adacd8739eeeb5de /src/check_stmt.cpp
parent3d7b92426081cd9f3197b13f7384a52dbac5379a (diff)
parent6ef779cd5c8260b2e6979e676d28489fd53dd599 (diff)
Merge branch 'master' into file-tags-without-comments
Diffstat (limited to 'src/check_stmt.cpp')
-rw-r--r--src/check_stmt.cpp18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp
index c8717ba98..74a9e8825 100644
--- a/src/check_stmt.cpp
+++ b/src/check_stmt.cpp
@@ -1641,6 +1641,8 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
Ast *expr = unparen_expr(rs->expr);
+ Operand rhs_operand = {};
+
bool is_range = false;
bool is_possibly_addressable = true;
isize max_val_count = 2;
@@ -1698,7 +1700,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
}
}
}
- bool is_ptr = is_type_pointer(type_deref(operand.type));
+ bool is_ptr = is_type_pointer(operand.type);
Type *t = base_type(type_deref(operand.type));
switch (t->kind) {
@@ -1750,16 +1752,19 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
break;
case Type_DynamicArray:
+ is_possibly_addressable = true;
array_add(&vals, t->DynamicArray.elem);
array_add(&vals, t_int);
break;
case Type_Slice:
+ is_possibly_addressable = true;
array_add(&vals, t->Slice.elem);
array_add(&vals, t_int);
break;
case Type_Map:
+ is_possibly_addressable = true;
is_map = true;
array_add(&vals, t->Map.key);
array_add(&vals, t->Map.value);
@@ -1781,6 +1786,8 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
case Type_Tuple:
{
+ is_possibly_addressable = false;
+
isize count = t->Tuple.variables.count;
if (count < 1) {
ERROR_BLOCK();
@@ -1810,8 +1817,6 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
array_add(&vals, e->type);
}
- is_possibly_addressable = false;
-
bool do_break = false;
for (isize i = rs->vals.count-1; i >= 0; i--) {
if (rs->vals[i] != nullptr && count < i+2) {
@@ -1831,6 +1836,11 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
case Type_Struct:
if (t->Struct.soa_kind != StructSoa_None) {
+ if (t->Struct.soa_kind == StructSoa_Fixed) {
+ is_possibly_addressable = operand.mode == Addressing_Variable || is_ptr;
+ } else {
+ is_possibly_addressable = true;
+ }
is_soa = true;
array_add(&vals, t->Struct.soa_elem);
array_add(&vals, t_int);
@@ -1907,7 +1917,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
if (is_possibly_addressable && i == addressable_index) {
entity->flags &= ~EntityFlag_Value;
} else {
- char const *idx_name = is_map ? "key" : is_bit_set ? "element" : "index";
+ char const *idx_name = is_map ? "key" : (is_bit_set || i == 0) ? "element" : "index";
error(token, "The %s variable '%.*s' cannot be made addressable", idx_name, LIT(str));
}
}