mirror of
https://github.com/ziglang/zig.git
synced 2024-12-03 10:28:48 +00:00
fix division by 0 crashing compiler
closes #99 closes #124 thanks to Michael Patraw for submitting a patch for this.
This commit is contained in:
parent
2bf6c28bc3
commit
a180168871
@ -2929,6 +2929,27 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import,
|
||||
return resolved_type;
|
||||
}
|
||||
|
||||
bool is_int = false;
|
||||
bool is_float = false;
|
||||
if (resolved_type->id == TypeTableEntryIdInt ||
|
||||
resolved_type->id == TypeTableEntryIdNumLitInt)
|
||||
{
|
||||
is_int = true;
|
||||
} else if ((resolved_type->id == TypeTableEntryIdFloat ||
|
||||
resolved_type->id == TypeTableEntryIdNumLitFloat) &&
|
||||
(bin_op_type == BinOpTypeAdd ||
|
||||
bin_op_type == BinOpTypeSub ||
|
||||
bin_op_type == BinOpTypeMult ||
|
||||
bin_op_type == BinOpTypeDiv ||
|
||||
bin_op_type == BinOpTypeMod))
|
||||
{
|
||||
is_float = true;
|
||||
} else {
|
||||
add_node_error(g, node, buf_sprintf("invalid operands to binary expression: '%s' and '%s'",
|
||||
buf_ptr(&lhs_type->name), buf_ptr(&rhs_type->name)));
|
||||
return g->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
ConstExprValue *op1_val = &get_resolved_expr(*op1)->const_val;
|
||||
ConstExprValue *op2_val = &get_resolved_expr(*op2)->const_val;
|
||||
if (!op1_val->ok || !op2_val->ok) {
|
||||
@ -2942,7 +2963,15 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import,
|
||||
} else if (bin_op_type == BinOpTypeMult) {
|
||||
return resolve_expr_const_val_as_bignum_op(g, node, bignum_mul, *op1, *op2, resolved_type);
|
||||
} else if (bin_op_type == BinOpTypeDiv) {
|
||||
return resolve_expr_const_val_as_bignum_op(g, node, bignum_div, *op1, *op2, resolved_type);
|
||||
ConstExprValue *op2_val = &get_resolved_expr(*op2)->const_val;
|
||||
if ((is_int && op2_val->data.x_bignum.data.x_uint == 0) ||
|
||||
(is_float && op2_val->data.x_bignum.data.x_float == 0.0))
|
||||
{
|
||||
add_node_error(g, node, buf_sprintf("division by zero is undefined"));
|
||||
return g->builtin_types.entry_invalid;
|
||||
} else {
|
||||
return resolve_expr_const_val_as_bignum_op(g, node, bignum_div, *op1, *op2, resolved_type);
|
||||
}
|
||||
} else if (bin_op_type == BinOpTypeMod) {
|
||||
return resolve_expr_const_val_as_bignum_op(g, node, bignum_mod, *op1, *op2, resolved_type);
|
||||
} else if (bin_op_type == BinOpTypeBinOr) {
|
||||
|
@ -1740,6 +1740,26 @@ fn f() {
|
||||
if (true) { }
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:9: error: condition is always true; unnecessary if statement");
|
||||
|
||||
|
||||
add_compile_fail_case("addition with non numbers", R"SOURCE(
|
||||
struct Foo {
|
||||
field: i32,
|
||||
}
|
||||
const x = Foo {.field = 1} + Foo {.field = 2};
|
||||
)SOURCE", 1, ".tmp_source.zig:5:28: error: invalid operands to binary expression: 'Foo' and 'Foo'");
|
||||
|
||||
|
||||
add_compile_fail_case("division by zero", R"SOURCE(
|
||||
const lit_int_x = 1 / 0;
|
||||
const lit_float_x = 1.0 / 0.0;
|
||||
const int_x = i32(1) / i32(0);
|
||||
const float_x = f32(1.0) / f32(0.0);
|
||||
)SOURCE", 4,
|
||||
".tmp_source.zig:2:21: error: division by zero is undefined",
|
||||
".tmp_source.zig:3:25: error: division by zero is undefined",
|
||||
".tmp_source.zig:4:22: error: division by zero is undefined",
|
||||
".tmp_source.zig:5:26: error: division by zero is undefined");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user