Commit a7570186eb
Changed files (2)
src
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,
test/compile_errors.zig
@@ -1809,4 +1809,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
\\}
,
".tmp_source.zig:3:25: error: attempt to cast negative value to unsigned integer");
+
+ cases.add("compile-time division by zero",
+ \\comptime {
+ \\ const a: i32 = 1;
+ \\ const b: i32 = 0;
+ \\ const c = a / b;
+ \\}
+ ,
+ ".tmp_source.zig:4:17: error: division by zero is undefined");
+
+ cases.add("compile-time remainder division by zero",
+ \\comptime {
+ \\ const a: i32 = 1;
+ \\ const b: i32 = 0;
+ \\ const c = a % b;
+ \\}
+ ,
+ ".tmp_source.zig:4:17: error: division by zero is undefined");
}