mirror of
https://github.com/odin-lang/Odin.git
synced 2026-05-24 20:59:52 +00:00
fix #6344: field-first index writes on #soa[dynamic]T and #soa[]T
This commit is contained in:
@@ -4654,6 +4654,8 @@ gb_internal lbAddr lb_build_addr_index_expr(lbProcedure *p, Ast *expr) {
|
||||
}
|
||||
}
|
||||
lbValue val = lb_emit_ptr_offset(p, field, index);
|
||||
// make sure it's ^T and not [^]T
|
||||
val.type = alloc_type_multi_pointer_to_pointer(val.type);
|
||||
return lb_addr(val);
|
||||
}
|
||||
|
||||
@@ -5795,8 +5797,8 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
|
||||
if (sub_sel.index.count > 0) {
|
||||
item = lb_emit_deep_field_gep(p, item, sub_sel);
|
||||
}
|
||||
// make sure it's ^T and not [^]T
|
||||
item.type = alloc_type_multi_pointer_to_pointer(item.type);
|
||||
// make sure it's ^T and not [^]T
|
||||
item.type = alloc_type_multi_pointer_to_pointer(item.type);
|
||||
|
||||
return lb_addr(item);
|
||||
} else if (addr.kind == lbAddr_Swizzle) {
|
||||
|
||||
@@ -36,6 +36,8 @@ $ODIN test ../test_issue_5699.odin $COMMON
|
||||
$ODIN test ../test_issue_6068.odin $COMMON
|
||||
$ODIN test ../test_issue_6101.odin $COMMON
|
||||
$ODIN test ../test_issue_6165.odin $COMMON
|
||||
$ODIN test ../test_issue_6344.odin $COMMON
|
||||
$ODIN test ../test_issue_6344.odin $COMMON -o:speed
|
||||
set +x
|
||||
|
||||
popd
|
||||
|
||||
72
tests/issues/test_issue_6344.odin
Normal file
72
tests/issues/test_issue_6344.odin
Normal file
@@ -0,0 +1,72 @@
|
||||
// Tests issue #6344 https://github.com/odin-lang/Odin/issues/6344
|
||||
package test_issues
|
||||
|
||||
import "core:testing"
|
||||
|
||||
@(test)
|
||||
test_soa_dynamic_field_write :: proc(t: ^testing.T) {
|
||||
V :: struct {
|
||||
x: f32,
|
||||
y: f32,
|
||||
}
|
||||
|
||||
array := make(#soa[dynamic]V, 4, 8)
|
||||
defer delete(array)
|
||||
|
||||
for i in 0 ..< 4 {
|
||||
array[i] = V{f32(i), f32(i) * 2}
|
||||
}
|
||||
|
||||
// Simple write through field-first indexing (was: compiler panic)
|
||||
for i in 0 ..< 4 {
|
||||
array.x[i] = f32(i) * 10
|
||||
}
|
||||
testing.expect_value(t, array[0].x, 0)
|
||||
testing.expect_value(t, array[1].x, 10)
|
||||
testing.expect_value(t, array[2].x, 20)
|
||||
testing.expect_value(t, array[3].x, 30)
|
||||
|
||||
// Compound write through field-first indexing (was: compiler panic)
|
||||
for i in 0 ..< 4 {
|
||||
array.x[i] += array.y[i]
|
||||
}
|
||||
testing.expect_value(t, array[0].x, 0)
|
||||
testing.expect_value(t, array[1].x, 12)
|
||||
testing.expect_value(t, array[2].x, 24)
|
||||
testing.expect_value(t, array[3].x, 36)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_soa_slice_field_write :: proc(t: ^testing.T) {
|
||||
V :: struct {
|
||||
x: f32,
|
||||
y: f32,
|
||||
}
|
||||
|
||||
array := make(#soa[dynamic]V, 4, 8)
|
||||
defer delete(array)
|
||||
|
||||
for i in 0 ..< 4 {
|
||||
array[i] = V{f32(i), f32(i) * 2}
|
||||
}
|
||||
|
||||
slice := array[:]
|
||||
|
||||
// Write through slice field-first indexing (was: compiler panic)
|
||||
for i in 0 ..< 4 {
|
||||
slice.x[i] = f32(i) * 10
|
||||
}
|
||||
testing.expect_value(t, array[0].x, 0)
|
||||
testing.expect_value(t, array[1].x, 10)
|
||||
testing.expect_value(t, array[2].x, 20)
|
||||
testing.expect_value(t, array[3].x, 30)
|
||||
|
||||
// Compound write through slice field-first indexing
|
||||
for i in 0 ..< 4 {
|
||||
slice.x[i] += slice.y[i]
|
||||
}
|
||||
testing.expect_value(t, array[0].x, 0)
|
||||
testing.expect_value(t, array[1].x, 12)
|
||||
testing.expect_value(t, array[2].x, 24)
|
||||
testing.expect_value(t, array[3].x, 36)
|
||||
}
|
||||
Reference in New Issue
Block a user