Sema: fix runtime safety for integer overflow with vectors

This commit is contained in:
Andrew Kelley 2022-07-28 21:40:57 -07:00
parent 1b1c70ce38
commit a7a6f38eeb
2 changed files with 20 additions and 12 deletions

View File

@ -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;

View File

@ -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;