From 36b41ce163843c9524d789e6edbc171c1d723e85 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Thu, 5 Jun 2025 07:31:03 -0400 Subject: [PATCH] Let compound literal array be broadcast to a struct field of arrays Fixes #4364 Patch courtesy of @cribalik --- src/llvm_backend_const.cpp | 11 +++++++++++ tests/issues/run.bat | 1 + tests/issues/run.sh | 1 + tests/issues/test_issue_4364.odin | 18 ++++++++++++++++++ 4 files changed, 31 insertions(+) create mode 100644 tests/issues/test_issue_4364.odin diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 02bb7473c..e897ae282 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -1054,9 +1054,20 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb } } + res.value = lb_build_constant_array_values(m, type, elem_type, cast(isize)type->Array.count, values, cc); + return res; + } else if (value.value_compound->tav.type == elem_type) { + // Compound is of array item type; expand its value to all items in array. + LLVMValueRef* values = gb_alloc_array(temporary_allocator(), LLVMValueRef, cast(isize)type->Array.count); + + for (isize i = 0; i < type->Array.count; i++) { + values[i] = lb_const_value(m, elem_type, value, cc).value; + } + res.value = lb_build_constant_array_values(m, type, elem_type, cast(isize)type->Array.count, values, cc); return res; } else { + // Assume that compound value is an array literal GB_ASSERT_MSG(elem_count == type->Array.count, "%td != %td", elem_count, type->Array.count); LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, cast(isize)type->Array.count); diff --git a/tests/issues/run.bat b/tests/issues/run.bat index bbe9b7ca6..8e71c3f3d 100644 --- a/tests/issues/run.bat +++ b/tests/issues/run.bat @@ -17,6 +17,7 @@ set COMMON=-define:ODIN_TEST_FANCY=false -file -vet -strict-style ..\..\..\odin test ..\test_issue_2637.odin %COMMON% || exit /b ..\..\..\odin test ..\test_issue_2666.odin %COMMON% || exit /b ..\..\..\odin test ..\test_issue_4210.odin %COMMON% || exit /b +..\..\..\odin test ..\test_issue_4364.odin %COMMON% || exit /b ..\..\..\odin test ..\test_issue_4584.odin %COMMON% || exit /b ..\..\..\odin build ..\test_issue_5043.odin %COMMON% || exit /b ..\..\..\odin build ..\test_issue_5097.odin %COMMON% || exit /b diff --git a/tests/issues/run.sh b/tests/issues/run.sh index 228efce7f..fc8ab513f 100755 --- a/tests/issues/run.sh +++ b/tests/issues/run.sh @@ -18,6 +18,7 @@ $ODIN test ../test_issue_2615.odin $COMMON $ODIN test ../test_issue_2637.odin $COMMON $ODIN test ../test_issue_2666.odin $COMMON $ODIN test ../test_issue_4210.odin $COMMON +$ODIN test ../test_issue_4364.odin $COMMON $ODIN test ../test_issue_4584.odin $COMMON if [[ $($ODIN build ../test_issue_2395.odin $COMMON 2>&1 >/dev/null | grep -c "Error:") -eq 2 ]] ; then echo "SUCCESSFUL 1/1" diff --git a/tests/issues/test_issue_4364.odin b/tests/issues/test_issue_4364.odin new file mode 100644 index 000000000..817a1a26b --- /dev/null +++ b/tests/issues/test_issue_4364.odin @@ -0,0 +1,18 @@ +// Tests issue #4364 https://github.com/odin-lang/Odin/issues/4364 +package test_issues + +import "core:testing" + +@test +test_const_array_fill_assignment :: proc(t: ^testing.T) { + MAGIC :: 12345 + Struct :: struct {x: int} + CONST_ARR : [4]Struct : Struct{MAGIC} + arr := CONST_ARR + + testing.expect_value(t, len(arr), 4) + testing.expect_value(t, arr[0], Struct{MAGIC}) + testing.expect_value(t, arr[1], Struct{MAGIC}) + testing.expect_value(t, arr[2], Struct{MAGIC}) + testing.expect_value(t, arr[3], Struct{MAGIC}) +}