From 41d08843ffd59e0ae1396dbf958bdd11257f384a Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Sun, 7 Jun 2026 03:03:17 -0500 Subject: [PATCH] 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 --- src/codegen/x86_64/CodeGen.zig | 2 +- test/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 index 8dc2a26f5a923644ee0c514863b8534c35f43da9..32c6552f78b51d0b0212908521bf08acdd3b0d3c 100644 --- 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 index 6557de08ca9dd687b2231436b3d48bf96e0dbbde..c9bdf8a5b09829f67165c09d71018b3602cafed9 100644 --- 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)); -- 2.54.0