authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-04 16:07:13+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-04 23:13:29+02:00
loge6b3cb5043b189fab6417df4a6921728ea174c8f
treefed95ca152b9d1425dd0922e6454898280869cb7
parent8c4faa5f3f63cfbcfdc12cda7c37be1da642d2f6

Sema: detect division overflow

Closes #13434

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

src/Sema.zig+18-12
...@@ -12469,10 +12469,12 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -12469,10 +12469,12 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1246912469
12470 if (maybe_rhs_val) |rhs_val| {12470 if (maybe_rhs_val) |rhs_val| {
12471 if (is_int) {12471 if (is_int) {
12472 return sema.addConstant(12472 const res = try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target);
12473 resolved_type,12473 var vector_index: usize = undefined;
12474 try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target),12474 if (!(try sema.intFitsInType(block, src, res, resolved_type, &vector_index))) {
12475 );12475 return sema.failWithIntegerOverflow(block, src, resolved_type, res, vector_index);
12476 }
12477 return sema.addConstant(resolved_type, res);
12476 } else {12478 } else {
12477 return sema.addConstant(12479 return sema.addConstant(
12478 resolved_type,12480 resolved_type,
...@@ -12584,10 +12586,12 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12584,10 +12586,12 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12584 if (modulus_val.compareWithZero(.neq)) {12586 if (modulus_val.compareWithZero(.neq)) {
12585 return sema.fail(block, src, "exact division produced remainder", .{});12587 return sema.fail(block, src, "exact division produced remainder", .{});
12586 }12588 }
12587 return sema.addConstant(12589 const res = try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target);
12588 resolved_type,12590 var vector_index: usize = undefined;
12589 try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target),12591 if (!(try sema.intFitsInType(block, src, res, resolved_type, &vector_index))) {
12590 );12592 return sema.failWithIntegerOverflow(block, src, resolved_type, res, vector_index);
12593 }
12594 return sema.addConstant(resolved_type, res);
12591 } else {12595 } else {
12592 const modulus_val = try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, target);12596 const modulus_val = try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, target);
12593 if (modulus_val.compareWithZero(.neq)) {12597 if (modulus_val.compareWithZero(.neq)) {
...@@ -12862,10 +12866,12 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12862,10 +12866,12 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1286212866
12863 if (maybe_rhs_val) |rhs_val| {12867 if (maybe_rhs_val) |rhs_val| {
12864 if (is_int) {12868 if (is_int) {
12865 return sema.addConstant(12869 const res = try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target);
12866 resolved_type,12870 var vector_index: usize = undefined;
12867 try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target),12871 if (!(try sema.intFitsInType(block, src, res, resolved_type, &vector_index))) {
12868 );12872 return sema.failWithIntegerOverflow(block, src, resolved_type, res, vector_index);
12873 }
12874 return sema.addConstant(resolved_type, res);
12869 } else {12875 } else {
12870 return sema.addConstant(12876 return sema.addConstant(
12871 resolved_type,12877 resolved_type,
test/cases/compile_errors/div_overflow.zig created+11
...@@ -0,0 +1,11 @@
1comptime {
2 const a = -128;
3 const b: i8 = -1;
4 _ = a / b;
5}
6
7// error
8// backend=stage2
9// target=native
10//
11// :4:11: error: overflow of integer type 'i8' with value '128'