Commit 3c53667db8

riverbl <94326797+riverbl@users.noreply.github.com>
2021-12-27 23:52:56
stage2: fix bug where performing wrapping or saturating arithmetic or saturating left shift on type comptime_int executed unreachable code
1 parent 5463499
Changed files (2)
src/Sema.zig
@@ -7474,7 +7474,10 @@ fn zirShl(
         }
         const val = switch (air_tag) {
             .shl_exact => return sema.fail(block, lhs_src, "TODO implement Sema for comptime shl_exact", .{}),
-            .shl_sat => try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, sema.mod.getTarget()),
+            .shl_sat => if (lhs_ty.zigTypeTag() == .ComptimeInt)
+                try lhs_val.shl(rhs_val, sema.arena)
+            else
+                try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, sema.mod.getTarget()),
             .shl => try lhs_val.shl(rhs_val, sema.arena),
             else => unreachable,
         };
@@ -8189,10 +8192,12 @@ fn analyzeArithmetic(
                         return casted_lhs;
                     }
                     if (maybe_lhs_val) |lhs_val| {
-                        return sema.addConstant(
-                            scalar_type,
-                            try lhs_val.intAddSat(rhs_val, scalar_type, sema.arena, target),
-                        );
+                        const val = if (scalar_tag == .ComptimeInt)
+                            try lhs_val.intAdd(rhs_val, sema.arena)
+                        else
+                            try lhs_val.intAddSat(rhs_val, scalar_type, sema.arena, target);
+
+                        return sema.addConstant(scalar_type, val);
                     } else break :rs .{ .src = lhs_src, .air_tag = .add_sat };
                 } else break :rs .{ .src = rhs_src, .air_tag = .add_sat };
             },
@@ -8280,10 +8285,12 @@ fn analyzeArithmetic(
                         return sema.addConstUndef(scalar_type);
                     }
                     if (maybe_rhs_val) |rhs_val| {
-                        return sema.addConstant(
-                            scalar_type,
-                            try lhs_val.intSubSat(rhs_val, scalar_type, sema.arena, target),
-                        );
+                        const val = if (scalar_tag == .ComptimeInt)
+                            try lhs_val.intSub(rhs_val, sema.arena)
+                        else
+                            try lhs_val.intSubSat(rhs_val, scalar_type, sema.arena, target);
+
+                        return sema.addConstant(scalar_type, val);
                     } else break :rs .{ .src = rhs_src, .air_tag = .sub_sat };
                 } else break :rs .{ .src = lhs_src, .air_tag = .sub_sat };
             },
@@ -8663,10 +8670,13 @@ fn analyzeArithmetic(
                         if (lhs_val.isUndef()) {
                             return sema.addConstUndef(scalar_type);
                         }
-                        return sema.addConstant(
-                            scalar_type,
-                            try lhs_val.intMulSat(rhs_val, scalar_type, sema.arena, target),
-                        );
+
+                        const val = if (scalar_tag == .ComptimeInt)
+                            try lhs_val.intMul(rhs_val, sema.arena)
+                        else
+                            try lhs_val.intMulSat(rhs_val, scalar_type, sema.arena, target);
+
+                        return sema.addConstant(scalar_type, val);
                     } else break :rs .{ .src = lhs_src, .air_tag = .mul_sat };
                 } else break :rs .{ .src = rhs_src, .air_tag = .mul_sat };
             },
src/value.zig
@@ -2275,6 +2275,10 @@ pub const Value = extern union {
     ) !Value {
         if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
 
+        if (ty.zigTypeTag() == .ComptimeInt) {
+            return intAdd(lhs, rhs, arena);
+        }
+
         if (ty.isAnyFloat()) {
             return floatAdd(lhs, rhs, ty, arena);
         }
@@ -2361,6 +2365,10 @@ pub const Value = extern union {
     ) !Value {
         if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
 
+        if (ty.zigTypeTag() == .ComptimeInt) {
+            return intSub(lhs, rhs, arena);
+        }
+
         if (ty.isAnyFloat()) {
             return floatSub(lhs, rhs, ty, arena);
         }
@@ -2440,6 +2448,10 @@ pub const Value = extern union {
     ) !Value {
         if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
 
+        if (ty.zigTypeTag() == .ComptimeInt) {
+            return intMul(lhs, rhs, arena);
+        }
+
         if (ty.isAnyFloat()) {
             return floatMul(lhs, rhs, ty, arena);
         }