diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 81d7a4e36..1685f9627 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -1,5 +1,14 @@ gb_internal lbValue lb_emit_arith_matrix(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type, bool component_wise); +gb_internal LLVMValueRef lb_const_low_bits_mask(LLVMTypeRef type, u64 bit_count) { + GB_ASSERT(bit_count <= 64); + if (bit_count == 0) { + return LLVMConstInt(type, 0, false); + } + u64 mask = bit_count == 64 ? ~0ull : (1ull<module; @@ -5148,13 +5157,7 @@ gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) { for (isize i = 0; i < fields.count; i++) { auto const &f = fields[i]; - LLVMValueRef mask = LLVMConstInt(lit, 1, false); - #if LLVM_VERSION_MAJOR >= 19 - mask = LLVMBuildShl(p->builder, mask, LLVMConstInt(lit, f.bit_size, false), ""); - #else - mask = LLVMConstShl(mask, LLVMConstInt(lit, f.bit_size, false)); - #endif - mask = LLVMConstSub(mask, LLVMConstInt(lit, 1, false)); + LLVMValueRef mask = lb_const_low_bits_mask(lit, f.bit_size); LLVMValueRef elem = values[i].value; if (lb_sizeof(lit) < lb_sizeof(LLVMTypeOf(elem))) { @@ -5200,13 +5203,7 @@ gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) { GB_ASSERT(mask_width > 0); bits_to_set -= mask_width; - LLVMValueRef mask = LLVMConstInt(vt, 1, false); - #if LLVM_VERSION_MAJOR >= 19 - mask = LLVMBuildShl(p->builder, mask, LLVMConstInt(vt, mask_width, false), ""); - #else - mask = LLVMConstShl(mask, LLVMConstInt(vt, mask_width, false)); - #endif - mask = LLVMConstSub(mask, LLVMConstInt(vt, 1, false)); + LLVMValueRef mask = lb_const_low_bits_mask(vt, mask_width); LLVMValueRef to_set = LLVMBuildAnd(p->builder, val, mask, ""); @@ -6076,4 +6073,3 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) { return {}; } - diff --git a/tests/issues/run.sh b/tests/issues/run.sh index 6c6796e28..e2e45dbfa 100755 --- a/tests/issues/run.sh +++ b/tests/issues/run.sh @@ -36,6 +36,7 @@ $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_6396.odin $COMMON if [[ $($ODIN build ../test_issue_6240.odin $COMMON 2>&1 >/dev/null | grep -c "Error:") -eq 3 ]] ; then echo "SUCCESSFUL 1/1" else diff --git a/tests/issues/test_issue_6396.odin b/tests/issues/test_issue_6396.odin new file mode 100644 index 000000000..5a0e7527c --- /dev/null +++ b/tests/issues/test_issue_6396.odin @@ -0,0 +1,23 @@ +// Tests issue #6396 https://github.com/odin-lang/Odin/issues/6396 +package test_issues + +import "core:testing" + +Issue6396_Full_Width_Field :: bit_field u32 { + a: u32 | 32, +} + +@test +test_issue_6396_full_width_bit_field_literal :: proc(t: ^testing.T) { + f0: Issue6396_Full_Width_Field = {a = 7} + testing.expect_value(t, f0.a, u32(7)) + + f0 = {a = 3} + testing.expect_value(t, f0.a, u32(3)) + + f0 = Issue6396_Full_Width_Field{a = 11} + testing.expect_value(t, f0.a, u32(11)) + + f0.a = 12 + testing.expect_value(t, f0.a, u32(12)) +}