Commit a7a6f38eeb

Andrew Kelley <andrew@ziglang.org>
2022-07-29 06:40:57
Sema: fix runtime safety for integer overflow with vectors
1 parent 1b1c70c
Changed files (2)
src/Sema.zig
@@ -11450,7 +11450,11 @@ fn addDivIntOverflowSafety(
     }
 
     const min_int = try resolved_type.minInt(sema.arena, target);
-    const neg_one = try Value.Tag.int_i64.create(sema.arena, -1);
+    const neg_one_scalar = try Value.Tag.int_i64.create(sema.arena, -1);
+    const neg_one = if (resolved_type.zigTypeTag() == .Vector)
+        try Value.Tag.repeated.create(sema.arena, neg_one_scalar)
+    else
+        neg_one_scalar;
 
     // If the LHS is comptime-known to be not equal to the min int,
     // no overflow is possible.
@@ -11467,17 +11471,11 @@ fn addDivIntOverflowSafety(
     if (resolved_type.zigTypeTag() == .Vector) {
         const vector_ty_ref = try sema.addType(resolved_type);
         if (maybe_lhs_val == null) {
-            const min_int_ref = try sema.addConstant(
-                resolved_type,
-                try Value.Tag.repeated.create(sema.arena, min_int),
-            );
+            const min_int_ref = try sema.addConstant(resolved_type, min_int);
             ok = try block.addCmpVector(casted_lhs, min_int_ref, .neq, vector_ty_ref);
         }
         if (maybe_rhs_val == null) {
-            const neg_one_ref = try sema.addConstant(
-                resolved_type,
-                try Value.Tag.repeated.create(sema.arena, neg_one),
-            );
+            const neg_one_ref = try sema.addConstant(resolved_type, neg_one);
             const rhs_ok = try block.addCmpVector(casted_rhs, neg_one_ref, .neq, vector_ty_ref);
             if (ok == .none) {
                 ok = rhs_ok;
src/type.zig
@@ -5201,10 +5201,20 @@ pub const Type = extern union {
         };
     }
 
+    // Works for vectors and vectors of integers.
+    pub fn minInt(ty: Type, arena: Allocator, target: Target) !Value {
+        const scalar = try minIntScalar(ty.scalarType(), arena, target);
+        if (ty.zigTypeTag() == .Vector) {
+            return Value.Tag.repeated.create(arena, scalar);
+        } else {
+            return scalar;
+        }
+    }
+
     /// Asserts that self.zigTypeTag() == .Int.
-    pub fn minInt(self: Type, arena: Allocator, target: Target) !Value {
-        assert(self.zigTypeTag() == .Int);
-        const info = self.intInfo(target);
+    pub fn minIntScalar(ty: Type, arena: Allocator, target: Target) !Value {
+        assert(ty.zigTypeTag() == .Int);
+        const info = ty.intInfo(target);
 
         if (info.signedness == .unsigned) {
             return Value.zero;