diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index d691cdb39..8bb1b057a 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -4680,6 +4680,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); } @@ -6092,8 +6094,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) { diff --git a/tests/issues/run.sh b/tests/issues/run.sh index 17b1b75e0..6eb2e09d3 100755 --- a/tests/issues/run.sh +++ b/tests/issues/run.sh @@ -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 $ODIN test ../test_issue_6396.odin $COMMON $ODIN test ../test_pr_6476.odin $COMMON diff --git a/tests/issues/test_issue_6344.odin b/tests/issues/test_issue_6344.odin new file mode 100644 index 000000000..834ca25db --- /dev/null +++ b/tests/issues/test_issue_6344.odin @@ -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) +}