diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-05-14 13:07:45 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-05-14 13:07:45 -0400 |
| commit | a7570186ebdffd97878a983b8e8a09902841e279 (patch) | |
| tree | 68ad4b544efe41eda086a8af5682ee383d5efbb7 /src | |
| parent | 63f6676fee83883736af794eaddb4d0ccb890c06 (diff) | |
| download | zig-a7570186ebdffd97878a983b8e8a09902841e279.tar.gz zig-a7570186ebdffd97878a983b8e8a09902841e279.zip | |
add compile error for comptime division by zero
closes #372
Diffstat (limited to 'src')
| -rw-r--r-- | src/ir.cpp | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 6a63597ed8..f506fa093b 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -8177,18 +8177,25 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp if (is_int && is_signed) { bool ok = false; if (instr_is_comptime(op1) && instr_is_comptime(op2)) { - BigNum trunc_result; - BigNum floor_result; - if (bignum_div_trunc(&trunc_result, &op1->value.data.x_bignum, &op2->value.data.x_bignum)) { - zig_unreachable(); - } - if (bignum_div_floor(&floor_result, &op1->value.data.x_bignum, &op2->value.data.x_bignum)) { - zig_unreachable(); - } - if (bignum_cmp_eq(&trunc_result, &floor_result)) { - ok = true; + if (op2->value.data.x_bignum.data.x_uint == 0) { + // the division by zero error will be caught later, but we don't have a + // division function ambiguity problem. op_id = IrBinOpDivTrunc; - } + ok = true; + } else { + BigNum trunc_result; + BigNum floor_result; + if (bignum_div_trunc(&trunc_result, &op1->value.data.x_bignum, &op2->value.data.x_bignum)) { + zig_unreachable(); + } + if (bignum_div_floor(&floor_result, &op1->value.data.x_bignum, &op2->value.data.x_bignum)) { + zig_unreachable(); + } + if (bignum_cmp_eq(&trunc_result, &floor_result)) { + ok = true; + op_id = IrBinOpDivTrunc; + } + } } if (!ok) { ir_add_error(ira, &bin_op_instruction->base, @@ -8204,15 +8211,23 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp if (is_signed) { bool ok = false; if (instr_is_comptime(op1) && instr_is_comptime(op2)) { - BigNum rem_result; - BigNum mod_result; - if (bignum_rem(&rem_result, &op1->value.data.x_bignum, &op2->value.data.x_bignum)) { - zig_unreachable(); - } - if (bignum_mod(&mod_result, &op1->value.data.x_bignum, &op2->value.data.x_bignum)) { - zig_unreachable(); + if ((is_int && op2->value.data.x_bignum.data.x_uint == 0) || + (!is_int && op2->value.data.x_bignum.data.x_float == 0.0)) + { + // the division by zero error will be caught later, but we don't + // have a remainder function ambiguity problem + ok = true; + } else { + BigNum rem_result; + BigNum mod_result; + if (bignum_rem(&rem_result, &op1->value.data.x_bignum, &op2->value.data.x_bignum)) { + zig_unreachable(); + } + if (bignum_mod(&mod_result, &op1->value.data.x_bignum, &op2->value.data.x_bignum)) { + zig_unreachable(); + } + ok = bignum_cmp_eq(&rem_result, &mod_result); } - ok = bignum_cmp_eq(&rem_result, &mod_result); } if (!ok) { ir_add_error(ira, &bin_op_instruction->base, |
