authorgravatar for brianferri@noreply.codeberg.orgbrianferri <brianferri@noreply.codeberg.org> 2026-08-28 09:18:00+02:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-08-28 09:18:00+02:00
log15435597d9a0505b93c3b7ffd3f3f95be5fa31f0
treeddb899767bfc6c6d9645363b487ca1b0eb450d7f
parenta4f0c4a91dd9c9ab67f2884e6461e6168267335e

Sema: reject non-integer lhs of a saturating shift

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/36510 Reviewed-by: mlugg <mlugg@mlugg.co.uk>

2 files changed, 18 insertions(+), 2 deletions(-)

src/Sema.zig+6-2
......@@ -12993,8 +12993,12 @@ fn zirShl(
1299312993 const scalar_rhs_ty = rhs_ty.scalarType(zcu);
1299412994
1299512995 // AstGen currently forces the rhs of `<<` to coerce to the correct type before the `.shl` instruction, so
12996 // we already know `scalar_rhs_ty` is valid for `.shl` -- we only need to validate for `.shl_sat`.
12997 if (air_tag == .shl_sat) _ = try sema.checkIntType(block, rhs_src, scalar_rhs_ty);
12996 // we already know `scalar_rhs_ty` is valid for `.shl`; likewise the lhs is validated when its
12997 // `typeof_log2_int_type` is evaluated. `.shl_sat` gets neither coercion, so validate both operands here.
12998 if (air_tag == .shl_sat) {
12999 _ = try sema.log2IntType(block, lhs_ty, lhs_src);
13000 _ = try sema.checkIntType(block, rhs_src, scalar_rhs_ty);
13001 }
1299813002
1299913003 const maybe_lhs_val = sema.resolveValue(lhs);
1300013004 const maybe_rhs_val = sema.resolveValue(rhs);
test/cases/compile_errors/saturating_shl_lhs_must_be_an_integer.zig created+12
......@@ -0,0 +1,12 @@
1export fn scalar() void {
2 _ = @as(f32, 1.5) <<| 2;
3}
4
5export fn vector() void {
6 _ = @Vector(2, f32){ 1.5, 2.5 } <<| @Vector(2, u8){ 1, 1 };
7}
8
9// error
10//
11// :2:9: error: bit shifting operation expected integer type, found 'f32'
12// :6:24: error: bit shifting operation expected integer type, found 'f32'