zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 41d08843ffd59e0ae1396dbf958bdd11257f384a (tree)
parent 3a8097ffd4a6370e8188767c6fff409e02186f72
Author: Devin J. Pohly <djpohly@gmail.com>
Date:   Sun,  7 Jun 2026 03:03:17 -0500

x86_64 backend: fix signed enum switch

Once the switch condition is been shifted up so the minimum value is 0,
it makes sense to treat its type as the unsigned version of its original
type.

Fixes #35651

Diffstat:
Msrc/codegen/x86_64/CodeGen.zig | 2+-
Mtest/behavior/enum.zig | 18++++++++++++++++++
2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/src/codegen/x86_64/CodeGen.zig b/src/codegen/x86_64/CodeGen.zig @@ -176662,7 +176662,7 @@ fn lowerSwitchBr( }; const condition_index_lock = cg.register_manager.lockReg(condition_index_reg); defer if (condition_index_lock) |lock| cg.register_manager.unlockReg(lock); - try cg.truncateRegister(condition_ty, condition_index_reg); + try cg.truncateRegister(unsigned_condition_ty, condition_index_reg); const ptr_size = @divExact(cg.target.ptrBitWidth(), 8); try cg.asmMemory(.{ ._mp, .j }, .{ .base = .table, diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig @@ -1313,6 +1313,24 @@ test "switch on an extern enum with negative value" { } } +test "switch on an enum with small signed tag type" { + const E = enum(i3) { + y = -2, + z = -1, + a = 0, + b = 1, + c = 2, + }; + + var runtime: E = .c; + _ = &runtime; + const result: u8 = switch (runtime) { + .y, .z, .a, .b => 0, + .c => 1, + }; + try expect(result == 1); +} + test "Non-exhaustive enum with nonstandard int size behaves correctly" { const E = enum(u15) { _ }; try expect(@sizeOf(E) == @sizeOf(u15));