Fix #3514 along with soa.a[i] bounds checking

This commit is contained in:
gingerBill
2024-05-16 16:18:21 +01:00
parent 330d6117e3
commit 32245e93a1
4 changed files with 49 additions and 20 deletions
+2 -2
View File
@@ -7806,8 +7806,8 @@ gb_internal bool check_set_index_data(Operand *o, Type *t, bool indirection, i64
if (is_type_pointer(original_type) && indirection) {
Type *ptr = base_type(original_type);
if (ptr->kind == Type_Pointer && o->mode == Addressing_SoaVariable) {
o->type = ptr->Pointer.elem;
if (ptr->kind == Type_MultiPointer && o->mode == Addressing_SoaVariable) {
o->type = ptr->MultiPointer.elem;
o->mode = Addressing_Value;
return true;
}
+12 -3
View File
@@ -2827,12 +2827,15 @@ gb_internal bool complete_soa_type(Checker *checker, Type *t, bool wait_to_finis
GB_ASSERT(soa_count >= 0);
field_type = alloc_type_array(old_field->type, soa_count);
} else {
field_type = alloc_type_pointer(old_field->type);
field_type = alloc_type_multi_pointer(old_field->type);
}
Entity *new_field = alloc_entity_field(scope, old_field->token, field_type, false, old_field->Variable.field_index);
t->Struct.fields[i] = new_field;
add_entity(scope, new_field);
new_field->flags |= EntityFlag_Used;
if (t->Struct.soa_kind != StructSoa_Fixed) {
new_field->flags |= EntityFlag_SoaPtrField;
}
} else {
t->Struct.fields[i] = old_field;
}
@@ -2948,7 +2951,7 @@ gb_internal Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_e
GB_ASSERT(count >= 0);
field_type = alloc_type_array(old_array->Array.elem, count);
} else {
field_type = alloc_type_pointer(old_array->Array.elem);
field_type = alloc_type_multi_pointer(old_array->Array.elem);
}
Token token = {};
token.string = params_xyzw[i];
@@ -2957,6 +2960,9 @@ gb_internal Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_e
soa_struct->Struct.fields[i] = new_field;
add_entity(ctx, scope, nullptr, new_field);
add_entity_use(ctx, nullptr, new_field);
if (soa_kind != StructSoa_Fixed) {
new_field->flags |= EntityFlag_SoaPtrField;
}
}
is_complete = true;
@@ -2980,12 +2986,15 @@ gb_internal Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_e
GB_ASSERT(count >= 0);
field_type = alloc_type_array(old_field->type, count);
} else {
field_type = alloc_type_pointer(old_field->type);
field_type = alloc_type_multi_pointer(old_field->type);
}
Entity *new_field = alloc_entity_field(scope, old_field->token, field_type, false, old_field->Variable.field_index);
soa_struct->Struct.fields[i] = new_field;
add_entity(ctx, scope, nullptr, new_field);
add_entity_use(ctx, nullptr, new_field);
if (soa_kind != StructSoa_Fixed) {
new_field->flags |= EntityFlag_SoaPtrField;
}
} else {
soa_struct->Struct.fields[i] = old_field;
}
+34 -14
View File
@@ -3851,27 +3851,39 @@ gb_internal lbAddr lb_build_addr_index_expr(lbProcedure *p, Ast *expr) {
if (ie->expr->tav.mode == Addressing_SoaVariable) {
// SOA Structures for slices/dynamic arrays
GB_ASSERT(is_type_pointer(type_of_expr(ie->expr)));
GB_ASSERT_MSG(is_type_multi_pointer(type_of_expr(ie->expr)), "%s", type_to_string(type_of_expr(ie->expr)));
lbValue field = lb_build_expr(p, ie->expr);
lbValue index = lb_build_expr(p, ie->index);
if (!build_context.no_bounds_check) {
// TODO HACK(bill): Clean up this hack to get the length for bounds checking
// GB_ASSERT(LLVMIsALoadInst(field.value));
Ast *se_expr = unparen_expr(ie->expr);
if (se_expr->kind == Ast_SelectorExpr) {
ast_node(se, SelectorExpr, se_expr);
lbValue len = {};
// lbValue a = {};
// a.value = LLVMGetOperand(field.value, 0);
// a.type = alloc_type_pointer(field.type);
Type *type = base_type(type_deref(type_of_expr(se->expr)));
GB_ASSERT_MSG(is_type_soa_struct(type), "%s", type_to_string(type));
if (type->Struct.soa_kind == StructSoa_Fixed) {
len = lb_const_int(p->module, t_int, type->Struct.soa_count);
} else {
lbAddr *found = map_get(&p->selector_addr, se_expr);
if (found) {
lbAddr addr = *found;
lbValue parent = lb_addr_get_ptr(p, addr);
if (is_type_pointer(type_deref(parent.type))) {
parent = lb_emit_load(p, parent);
}
len = lb_soa_struct_len(p, parent);
}
}
// irInstr *b = &a->Instr;
// GB_ASSERT(b->kind == irInstr_StructElementPtr);
// lbValue base_struct = b->StructElementPtr.address;
// GB_ASSERT(is_type_soa_struct(type_deref(ir_type(base_struct))));
// lbValue len = ir_soa_struct_len(p, base_struct);
// lb_emit_bounds_check(p, ast_token(ie->index), index, len);
if (len.value) {
lb_emit_bounds_check(p, ast_token(ie->index), index, len);
}
} else {
// TODO(bill): how do you even do bounds checking here?
}
}
lbValue val = lb_emit_ptr_offset(p, field, index);
return lb_addr(val);
@@ -4218,6 +4230,7 @@ gb_internal lbAddr lb_build_addr_slice_expr(lbProcedure *p, Ast *expr) {
lbValue field_dst = lb_emit_struct_ep(p, dst.addr, i);
lbValue field_src = lb_emit_struct_ep(p, lb_addr_get_ptr(p, addr), i);
field_src = lb_emit_array_ep(p, field_src, low);
field_src = lb_emit_conv(p, field_src, type_deref(field_dst.type));
lb_emit_store(p, field_dst, field_src);
}
@@ -4233,6 +4246,7 @@ gb_internal lbAddr lb_build_addr_slice_expr(lbProcedure *p, Ast *expr) {
lbValue field_dst = lb_emit_struct_ep(p, dst.addr, i);
lbValue field_src = lb_emit_struct_ev(p, base, i);
field_src = lb_emit_ptr_offset(p, field_src, low);
field_src = lb_emit_conv(p, field_src, type_deref(field_dst.type));
lb_emit_store(p, field_dst, field_src);
}
@@ -4247,6 +4261,7 @@ gb_internal lbAddr lb_build_addr_slice_expr(lbProcedure *p, Ast *expr) {
lbValue field_dst = lb_emit_struct_ep(p, dst.addr, i);
lbValue field_src = lb_emit_struct_ev(p, base, i);
field_src = lb_emit_ptr_offset(p, field_src, low);
field_src = lb_emit_conv(p, field_src, type_deref(field_dst.type));
lb_emit_store(p, field_dst, field_src);
}
@@ -4989,6 +5004,11 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
sel.index[0] = addr.swizzle.indices[sel.index[0]];
}
Type *atype = type_deref(lb_addr_type(addr));
if (is_type_soa_struct(atype)) {
map_set(&p->selector_addr, expr, addr);
}
lbValue a = lb_addr_get_ptr(p, addr);
a = lb_emit_deep_field_gep(p, a, sel);
return lb_addr(a);
+1 -1
View File
@@ -1324,7 +1324,7 @@ gb_internal lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) {
for (isize i = 0; i < field_count; i++) {
Entity *field = t->Struct.fields[i];
Type *base_type = field->type;
GB_ASSERT(base_type->kind == Type_Pointer);
GB_ASSERT(base_type->kind == Type_MultiPointer);
lbValue dst = lb_emit_struct_ep(p, res.addr, cast(i32)i);
lbValue src_ptr = lb_emit_struct_ep(p, addr.addr, cast(i32)i);