authorgravatar for justus@klausecker.deJustus Klausecker <justus@klausecker.de> 2025-08-07 02:08:40+02:00
committergravatar for justus@klausecker.deJustus Klausecker <justus@klausecker.de> 2025-08-12 16:33:57+02:00
log0ef26d113ae5a8b307a3af76db61706846fea22f
tree2caf4a84834fbc2059f851629ff9933ca0dc3cae
parentd0586da18e08d0b8bdc2347fabdc0ba531901641

make `>>` a compile error with any undef arg ; add a bunch of test cases


8 files changed, 65 insertions(+), 32 deletions(-)

src/Sema.zig+7-15
...@@ -13826,11 +13826,9 @@ fn zirShr(...@@ -13826,11 +13826,9 @@ fn zirShr(
13826 else => unreachable,13826 else => unreachable,
13827 })).toIntern());13827 })).toIntern());
13828 }13828 }
13829 if (rhs_val.isUndef(zcu)) switch (air_tag) {13829 if (rhs_val.isUndef(zcu)) {
13830 .shr => return pt.undefRef(lhs_ty),13830 return sema.failWithUseOfUndef(block, rhs_src, null);
13831 .shr_exact => return sema.failWithUseOfUndef(block, rhs_src, null),13831 }
13832 else => unreachable,
13833 };
13834 const bits_val = try pt.intValue(.comptime_int, scalar_ty.intInfo(zcu).bits);13832 const bits_val = try pt.intValue(.comptime_int, scalar_ty.intInfo(zcu).bits);
13835 switch (rhs_ty.zigTypeTag(zcu)) {13833 switch (rhs_ty.zigTypeTag(zcu)) {
13836 .int, .comptime_int => {13834 .int, .comptime_int => {
...@@ -13849,11 +13847,9 @@ fn zirShr(...@@ -13849,11 +13847,9 @@ fn zirShr(
13849 var elem_idx: usize = 0;13847 var elem_idx: usize = 0;
13850 while (elem_idx < rhs_ty.vectorLen(zcu)) : (elem_idx += 1) {13848 while (elem_idx < rhs_ty.vectorLen(zcu)) : (elem_idx += 1) {
13851 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);13849 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
13852 if (rhs_elem.isUndef(zcu)) switch (air_tag) {13850 if (rhs_elem.isUndef(zcu)) {
13853 .shr => continue,13851 return sema.failWithUseOfUndef(block, rhs_src, elem_idx);
13854 .shr_exact => return sema.failWithUseOfUndef(block, rhs_src, elem_idx),13852 }
13855 else => unreachable,
13856 };
13857 switch (try rhs_elem.orderAgainstZeroSema(pt)) {13853 switch (try rhs_elem.orderAgainstZeroSema(pt)) {
13858 .gt => {13854 .gt => {
13859 if (try rhs_elem.compareHeteroSema(.gte, bits_val, pt)) {13855 if (try rhs_elem.compareHeteroSema(.gte, bits_val, pt)) {
...@@ -13875,11 +13871,7 @@ fn zirShr(...@@ -13875,11 +13871,7 @@ fn zirShr(
13875 return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{});13871 return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{});
13876 }13872 }
13877 if (maybe_lhs_val) |lhs_val| {13873 if (maybe_lhs_val) |lhs_val| {
13878 switch (air_tag) {13874 try sema.checkAllScalarsDefined(block, lhs_src, lhs_val);
13879 .shr => if (lhs_val.isUndef(zcu)) return pt.undefRef(lhs_ty),
13880 .shr_exact => try sema.checkAllScalarsDefined(block, lhs_src, lhs_val),
13881 else => unreachable,
13882 }
13883 }13875 }
13884 }13876 }
13885 break :rs rhs_src;13877 break :rs rhs_src;
src/Sema/arith.zig+3-10
...@@ -1221,16 +1221,9 @@ fn shrScalar(...@@ -1221,16 +1221,9 @@ fn shrScalar(
1221 const pt = sema.pt;1221 const pt = sema.pt;
1222 const zcu = pt.zcu;1222 const zcu = pt.zcu;
12231223
1224 switch (op) {1224 if (lhs_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, lhs_src, vec_idx);
1225 .shr => {1225 if (rhs_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, rhs_src, vec_idx);
1226 if (lhs_val.isUndef(zcu)) return lhs_val;1226
1227 if (rhs_val.isUndef(zcu)) return pt.undefValue(lhs_ty);
1228 },
1229 .shr_exact => {
1230 if (lhs_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, lhs_src, vec_idx);
1231 if (rhs_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, rhs_src, vec_idx);
1232 },
1233 }
1234 switch (try rhs_val.orderAgainstZeroSema(pt)) {1227 switch (try rhs_val.orderAgainstZeroSema(pt)) {
1235 .gt => {},1228 .gt => {},
1236 .eq => return lhs_val,1229 .eq => return lhs_val,
test/behavior/bit_shifting.zig-7
...@@ -196,10 +196,3 @@ test "Saturating Shift Left" {...@@ -196,10 +196,3 @@ test "Saturating Shift Left" {
196 try expectEqual(170141183460469231731687303715884105727, S.shlSat(@as(i128, 0x2fe6bc5448c55ce18252e2c9d4477750), 0x31));196 try expectEqual(170141183460469231731687303715884105727, S.shlSat(@as(i128, 0x2fe6bc5448c55ce18252e2c9d4477750), 0x31));
197 try expectEqual(0, S.shlSat(@as(i128, 0), 127));197 try expectEqual(0, S.shlSat(@as(i128, 0), 127));
198}198}
199
200test "shift by partially undef vector" {
201 comptime {
202 const a: @Vector(1, u8) = .{undefined};
203 _ = a >> @splat(4);
204 }
205}
test/cases/compile_errors/shl_exact_on_undefined_value.zig created+11
...@@ -0,0 +1,11 @@
1comptime {
2 var a: i64 = undefined;
3 var b: u6 = undefined;
4 _ = &a;
5 _ = &b;
6 _ = @shlExact(a, b);
7}
8
9// error
10//
11// :6:19: error: use of undefined value here causes illegal behavior
test/cases/compile_errors/shl_on_undefined_value.zig created+11
...@@ -0,0 +1,11 @@
1comptime {
2 var a: i64 = undefined;
3 var b: u6 = undefined;
4 _ = &a;
5 _ = &b;
6 _ = a << b;
7}
8
9// error
10//
11// :6:9: error: use of undefined value here causes illegal behavior
test/cases/compile_errors/shl_with_overflow_on_undefined_value.zig created+11
...@@ -0,0 +1,11 @@
1comptime {
2 var a: i64 = undefined;
3 var b: u6 = undefined;
4 _ = &a;
5 _ = &b;
6 _ = @shlWithOverflow(a, b);
7}
8
9// error
10//
11// :6:26: error: use of undefined value here causes illegal behavior
test/cases/compile_errors/shr_exact_on_undefined_value.zig created+11
...@@ -0,0 +1,11 @@
1comptime {
2 var a: i64 = undefined;
3 var b: u6 = undefined;
4 _ = &a;
5 _ = &b;
6 _ = @shrExact(a, b);
7}
8
9// error
10//
11// :6:19: error: use of undefined value here causes illegal behavior
test/cases/compile_errors/shr_on_undefined_value.zig created+11
...@@ -0,0 +1,11 @@
1comptime {
2 var a: i64 = undefined;
3 var b: u6 = undefined;
4 _ = &a;
5 _ = &b;
6 _ = a >> b;
7}
8
9// error
10//
11// :6:9: error: use of undefined value here causes illegal behavior