diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v index 9c766c6ccf..6055193c7f 100644 --- a/vlib/v/checker/assign.v +++ b/vlib/v/checker/assign.v @@ -212,9 +212,9 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { if left_type == ast.int_type { if mut right is ast.IntegerLiteral { mut is_large := right.val.len > 13 - if !is_large && right.val.len > 8 { + if !is_large && right.val.len > 9 { val := right.val.i64() - is_large = val > int_max || val < int_min + is_large = overflows_i32(val) } if is_large { c.error('overflow in implicit type `int`, use explicit type casting instead', diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index bc82b9469d..1773b8b991 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -15,8 +15,6 @@ import v.pkgconfig import v.transformer import v.comptime -const int_min = int(0x80000000) -const int_max = int(0x7FFFFFFF) // prevent stack overflows by restricting too deep recursion: const expr_level_cutoff_limit = 40 const stmt_level_cutoff_limit = 40 @@ -1792,9 +1790,9 @@ fn (mut c Checker) const_decl(mut node ast.ConstDecl) { if field.typ == ast.int_type { if mut field.expr is ast.IntegerLiteral { mut is_large := field.expr.val.len > 13 - if !is_large && field.expr.val.len > 8 { + if !is_large && field.expr.val.len > 9 { val := field.expr.val.i64() - is_large = val > checker.int_max || val < checker.int_min + is_large = overflows_i32(val) } if is_large { c.error('overflow in implicit type `int`, use explicit type casting instead', diff --git a/vlib/v/checker/comptime.v b/vlib/v/checker/comptime.v index e8ffceb5e2..27a6b7a3ef 100644 --- a/vlib/v/checker/comptime.v +++ b/vlib/v/checker/comptime.v @@ -402,6 +402,9 @@ fn (mut c Checker) eval_comptime_const_expr(expr ast.Expr, nlevel int) ?ast.Comp if expr.typ == ast.i64_type { return cast_expr_value.i64() or { return none } } + if expr.typ == ast.int_type { + return cast_expr_value.i64() or { return none } + } // if expr.typ == ast.u8_type { return cast_expr_value.u8() or { return none } @@ -1021,3 +1024,27 @@ fn (mut c Checker) pop_comptime_info() { c.comptime.comptime_for_method = old.comptime_for_method c.comptime.comptime_for_method_ret_type = old.comptime_for_method_ret_type } + +fn overflows_i8(val i64) bool { + return val > max_i8 || val < min_i8 +} + +fn overflows_i16(val i64) bool { + return val > max_i16 || val < min_i16 +} + +fn overflows_i32(val i64) bool { + return val > max_i32 || val < min_i32 +} + +fn overflows_u8(val i64) bool { + return val > max_u8 || val < min_u8 +} + +fn overflows_u16(val i64) bool { + return val > max_u16 || val < min_u16 +} + +fn overflows_u32(val i64) bool { + return val > max_u32 || val < min_u32 +} diff --git a/vlib/v/tests/fixed_array_const_size_test.v b/vlib/v/tests/fixed_array_const_size_test.v index f9787c9d3f..d6c3724d74 100644 --- a/vlib/v/tests/fixed_array_const_size_test.v +++ b/vlib/v/tests/fixed_array_const_size_test.v @@ -2,6 +2,7 @@ const size = 5 const u64_size = u64(5) const int_size = int(1) const infix_cast_size = int(100 / 50) +const int_sizeof_cast_size = ((1600 / 8) / int(sizeof(u64))) struct Foo { bar [size]u8 @@ -105,3 +106,8 @@ fn test_infix_const_expr_used_as_fixed_array_size() { println(mat6) assert mat6.data.len == 6 } + +fn test_int_sizeof_size() { + arr_fixed := [int_sizeof_cast_size]int{} + assert arr_fixed.len == 25 +}