From 4a3a7a92cbfcdcfd33826fd4a2e9e593b48e77f2 Mon Sep 17 00:00:00 2001 From: Louis Novy <101842021+louisnovy@users.noreply.github.com> Date: Fri, 2 Oct 2026 09:18:30 -0400 Subject: [PATCH] Fix the length of fixed capacity dynamic array literals whose elements can't be constant --- src/llvm_backend_expr.cpp | 7 +++++-- tests/issues/run.bat | 1 + tests/issues/run.sh | 1 + tests/issues/test_issue_7430.odin | 13 +++++++++++++ 4 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 tests/issues/test_issue_7430.odin diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 0e90d8d74..cfa31344c 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -6458,13 +6458,16 @@ gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) { case Type_FixedCapacityDynamicArray: { if (cl->elems.count > 0) { - lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr))); + // NOTE: the length isn't taken from the literal's constant, which is nil when its elements can't be constant + lbValue dst_ptr = lb_addr_get_ptr(p, v); + lbValue value = lb_const_value(p->module, type, exact_value_compound(expr)); + lb_emit_store(p, lb_emit_struct_ep(p, dst_ptr, 0), lb_emit_struct_ev(p, value, 0)); + lb_emit_store(p, lb_emit_struct_ep(p, dst_ptr, 1), lb_const_int(p->module, t_int, cl->max_count)); auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); lb_build_addr_compound_lit_populate(p, cl->elems, &temp_data, type); - lbValue dst_ptr = lb_addr_get_ptr(p, v); for_array(i, temp_data) { i32 index = cast(i32)(temp_data[i].elem_index); temp_data[i].gep = lb_emit_array_epi(p, dst_ptr, index); diff --git a/tests/issues/run.bat b/tests/issues/run.bat index 5c92eb840..a276b04a7 100644 --- a/tests/issues/run.bat +++ b/tests/issues/run.bat @@ -59,6 +59,7 @@ set COMMON=-define:ODIN_TEST_FANCY=false -file -vet -strict-style -ignore-unused ..\..\..\odin build ..\test_issue_7037.odin %COMMON% -o:none || exit /b ..\..\..\odin test ..\test_issue_7421.odin %COMMON% || exit /b ..\..\..\odin check ..\test_issue_7421_tagged_duplicate.odin %COMMON% 2>&1 | find /c "Error: Duplicate case" | findstr /x "1" || exit /b +..\..\..\odin test ..\test_issue_7430.odin %COMMON% || exit /b ..\..\..\odin build ..\test_issue_7188.odin %COMMON% || exit /b clang -c ..\test_issue_sysv_abi.c -o test_issue_sysv_abi_c.o || exit /b ..\..\..\odin test ..\test_issue_sysv_abi.odin %COMMON% || exit /b diff --git a/tests/issues/run.sh b/tests/issues/run.sh index 22b84524f..53c4aa855 100755 --- a/tests/issues/run.sh +++ b/tests/issues/run.sh @@ -112,6 +112,7 @@ else exit 1 fi $ODIN check ../test_issue_7429.odin $COMMON_CHECK +$ODIN test ../test_issue_7430.odin $COMMON $ODIN test ../test_issue_7356.odin $COMMON $ODIN test ../test_issue_7336.odin $COMMON $ODIN build ../test_issue_7167.odin $COMMON diff --git a/tests/issues/test_issue_7430.odin b/tests/issues/test_issue_7430.odin new file mode 100644 index 000000000..edf248356 --- /dev/null +++ b/tests/issues/test_issue_7430.odin @@ -0,0 +1,13 @@ +// Tests issue #7430 https://github.com/odin-lang/Odin/issues/7430 +package test_issues + +import "core:testing" + +@(test) +test_issue_7430 :: proc(t: ^testing.T) { + U :: union {T} + T :: struct {_: []i32} + + u := [dynamic; 4]U{T{}} + testing.expect_value(t, len(u), 1) +}