authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-28 21:40:57-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-29 11:03:12-07:00
loga7a6f38eebfa2bf6dbe4d5f9579f0b2d54593820
tree59ca1c44c953519deff4aeb42bca40d8ab5c72eb
parent1b1c70ce381cc3c76517c846eafcd3425a40ce9c

Sema: fix runtime safety for integer overflow with vectors


2 files changed, 20 insertions(+), 12 deletions(-)

src/Sema.zig+7-9
...@@ -11450,7 +11450,11 @@ fn addDivIntOverflowSafety(...@@ -11450,7 +11450,11 @@ fn addDivIntOverflowSafety(
11450 }11450 }
1145111451
11452 const min_int = try resolved_type.minInt(sema.arena, target);11452 const min_int = try resolved_type.minInt(sema.arena, target);
11453 const neg_one = try Value.Tag.int_i64.create(sema.arena, -1);11453 const neg_one_scalar = try Value.Tag.int_i64.create(sema.arena, -1);
11454 const neg_one = if (resolved_type.zigTypeTag() == .Vector)
11455 try Value.Tag.repeated.create(sema.arena, neg_one_scalar)
11456 else
11457 neg_one_scalar;
1145411458
11455 // If the LHS is comptime-known to be not equal to the min int,11459 // If the LHS is comptime-known to be not equal to the min int,
11456 // no overflow is possible.11460 // no overflow is possible.
...@@ -11467,17 +11471,11 @@ fn addDivIntOverflowSafety(...@@ -11467,17 +11471,11 @@ fn addDivIntOverflowSafety(
11467 if (resolved_type.zigTypeTag() == .Vector) {11471 if (resolved_type.zigTypeTag() == .Vector) {
11468 const vector_ty_ref = try sema.addType(resolved_type);11472 const vector_ty_ref = try sema.addType(resolved_type);
11469 if (maybe_lhs_val == null) {11473 if (maybe_lhs_val == null) {
11470 const min_int_ref = try sema.addConstant(11474 const min_int_ref = try sema.addConstant(resolved_type, min_int);
11471 resolved_type,
11472 try Value.Tag.repeated.create(sema.arena, min_int),
11473 );
11474 ok = try block.addCmpVector(casted_lhs, min_int_ref, .neq, vector_ty_ref);11475 ok = try block.addCmpVector(casted_lhs, min_int_ref, .neq, vector_ty_ref);
11475 }11476 }
11476 if (maybe_rhs_val == null) {11477 if (maybe_rhs_val == null) {
11477 const neg_one_ref = try sema.addConstant(11478 const neg_one_ref = try sema.addConstant(resolved_type, neg_one);
11478 resolved_type,
11479 try Value.Tag.repeated.create(sema.arena, neg_one),
11480 );
11481 const rhs_ok = try block.addCmpVector(casted_rhs, neg_one_ref, .neq, vector_ty_ref);11479 const rhs_ok = try block.addCmpVector(casted_rhs, neg_one_ref, .neq, vector_ty_ref);
11482 if (ok == .none) {11480 if (ok == .none) {
11483 ok = rhs_ok;11481 ok = rhs_ok;
src/type.zig+13-3
...@@ -5201,10 +5201,20 @@ pub const Type = extern union {...@@ -5201,10 +5201,20 @@ pub const Type = extern union {
5201 };5201 };
5202 }5202 }
52035203
5204 // Works for vectors and vectors of integers.
5205 pub fn minInt(ty: Type, arena: Allocator, target: Target) !Value {
5206 const scalar = try minIntScalar(ty.scalarType(), arena, target);
5207 if (ty.zigTypeTag() == .Vector) {
5208 return Value.Tag.repeated.create(arena, scalar);
5209 } else {
5210 return scalar;
5211 }
5212 }
5213
5204 /// Asserts that self.zigTypeTag() == .Int.5214 /// Asserts that self.zigTypeTag() == .Int.
5205 pub fn minInt(self: Type, arena: Allocator, target: Target) !Value {5215 pub fn minIntScalar(ty: Type, arena: Allocator, target: Target) !Value {
5206 assert(self.zigTypeTag() == .Int);5216 assert(ty.zigTypeTag() == .Int);
5207 const info = self.intInfo(target);5217 const info = ty.intInfo(target);
52085218
5209 if (info.signedness == .unsigned) {5219 if (info.signedness == .unsigned) {
5210 return Value.zero;5220 return Value.zero;