Sema: detect division overflow

Closes #13434
This commit is contained in:
Veikka Tuominen 2022-11-04 16:07:13 +02:00
parent 8c4faa5f3f
commit e6b3cb5043
2 changed files with 29 additions and 12 deletions

View File

@ -12469,10 +12469,12 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
if (maybe_rhs_val) |rhs_val| {
if (is_int) {
return sema.addConstant(
resolved_type,
try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target),
);
const res = try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target);
var vector_index: usize = undefined;
if (!(try sema.intFitsInType(block, src, res, resolved_type, &vector_index))) {
return sema.failWithIntegerOverflow(block, src, resolved_type, res, vector_index);
}
return sema.addConstant(resolved_type, res);
} else {
return sema.addConstant(
resolved_type,
@ -12584,10 +12586,12 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
if (modulus_val.compareWithZero(.neq)) {
return sema.fail(block, src, "exact division produced remainder", .{});
}
return sema.addConstant(
resolved_type,
try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target),
);
const res = try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target);
var vector_index: usize = undefined;
if (!(try sema.intFitsInType(block, src, res, resolved_type, &vector_index))) {
return sema.failWithIntegerOverflow(block, src, resolved_type, res, vector_index);
}
return sema.addConstant(resolved_type, res);
} else {
const modulus_val = try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, target);
if (modulus_val.compareWithZero(.neq)) {
@ -12862,10 +12866,12 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
if (maybe_rhs_val) |rhs_val| {
if (is_int) {
return sema.addConstant(
resolved_type,
try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target),
);
const res = try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target);
var vector_index: usize = undefined;
if (!(try sema.intFitsInType(block, src, res, resolved_type, &vector_index))) {
return sema.failWithIntegerOverflow(block, src, resolved_type, res, vector_index);
}
return sema.addConstant(resolved_type, res);
} else {
return sema.addConstant(
resolved_type,

View File

@ -0,0 +1,11 @@
comptime {
const a = -128;
const b: i8 = -1;
_ = a / b;
}
// error
// backend=stage2
// target=native
//
// :4:11: error: overflow of integer type 'i8' with value '128'